ASP.NET5之客户端开发:Grunt和Gulp构建工具在Visual Studio 2015中的高效的应用
Grunt和Gulp是Javascript世界里的用来做自动压缩、Typescript编译、代码质量lint工具、css预处理器的构建工具,它帮助开发者处理客户端开发中的一些烦操重复性的工作。Grunt和Gulp都在Visual studio 2015中得到支持。ASP.NET 项目模板默认使用Gulp。
Grunt和Gulp
Grunt和Gulp有什么区别?Gulp虽然是稍微晚一点登场的,但是它因crisp performance和优雅的语法受到欢迎。与Grunt不同,Grunt往往在硬盘上是读写文件,Gulp使用流式的API去链式的调用方法,Grunt是早些出现的客户端构建工具,Grunt预定义了大多数经常要做的压缩和单元测试等工作。Grunt每天都有数以千计的下载和应用。
使用Grunt
这个实例使用Empty ASP.NET项目模板来展示自动化的客户端构建工作。非空的ASP.NET项目模板默认使用Gulp。
最终示例清理目标部署目录,合并Javascript文件,检查代码质量,压缩Javascript文件内容并且部署到web项目的跟目录,我们将使用以下包:
grunt:任务执行者包;
grunt-contrib-clean:一个用来移除文件和目录的任务
grunt-contrib-jshint:一个审查代码质量的任务
grunt-contrib-concat:一个连接多文件在一个文件中的任务
grunt-contrib-uglify:一个压缩和缩小文件尺寸的任务
grunt-contrib-watch:一个检测文件活动的任务
准备项目
首先,创建信的空的Web应用程序添加示例的Typescript文件,Typescript文件在Visual Studio 2015的默认设置下,会自动地编译为Javascript中并且作为Grunt的源文件。
- 在Vistual Studio 2015中,创建新的ASP.NET应用程序。
- 在“新ASP.NET项目”对话框中,选择ASP.NET Empty模板并且单击OK按钮。
- 在解决方案管理器中,可以看到项目的目录结构,Src文件夹包含一个空的wwwroot和dependencies节点
- 在项目中添加一个名为Typescript的文件夹
- 在添加任何文件之前,确认Visual Studio 2015打开了“保存时编译”的项目(在“工具->选项->文本编辑器->Typescript=>项目”节点下)
- 右击Typescript目录,点击”添加->新项目”选择Javascript项目命名为Tastes.ts(注意ts后缀),拷贝下列代码
enum Tastes { Sweet, Sour, Salty, Bitter }
- 在Typescript目录中添加第二个文件命名为Food.ts,拷贝以下代码
class Food {
constructor(name: string, calories: number) {
this._name = name;
this._calories = calories;
} private _name: string;
get Name() {
return this._name;
} private _calories: number;
get Calories() {
return this._calories;
} private _taste: Tastes;
get Taste(): Tastes { return this._taste }
set Taste(value: Tastes) {
this._taste = value;
}
}
配置NPM
下一步,配置npm来下来grunt和grunt-tasks
- 在解决方案目录中,右击并选择“添加->新项目”选择npm configuration file,保留默认的文件名,点击确定按钮
- 在package.json文件中,在devDependencies属性下,输入grunt,使用只能提示选择grunt并回车,添加冒号,并使用智能提示选择版本号
- 添加我们需要的更多的依赖项目
- 保存文件
这些包将会被自动下载,你可以在node-modules目录下看到下载的内容,前提是你打开了”显示所有文件“
如果需要的话,你要可以通过右键单击dependences下的NPM,选择Restore Packages按钮恢复这些包
配置Grunt
Grunt使用名为gruntfile.js的文件清单进行配置、加载和注册任务,让它可以手动的运行或者基数Vistual Studio的事件机制自动运行
- 右键单击项目文件,选择”添加->新项目“,选择”Grunt configuration file”选项,保留默认的文件名,并点击添加按钮
初始的文件包含了grunt.initConfig()方法,这个方法就是我们用来设置选项的地方module.exports = function (grunt) {
grunt.initConfig({
});
}; - 在上文的方法中,添加clean任务,这个配置可以添加一个数组来定义要清理的目录或者文件
module.exports = function (grunt) {
grunt.initConfig({
clean: ["wwwroot/lib/*", "temp/"],
});
}; - 在initConfig方法下方,我们需要调用grunt.loadNpmTasks方法来让任务在Visual Studio中运行
grunt.loadNpmTasks("grunt-contrib-clean");
- 保存这个文件,文件内容如下所示
module.exports = function (grunt) {
grunt.initConfig({
clean: ["wwwroot/lib/*", "temp/"],
});
grunt.loadNpmTasks("grunt-contrib-clean");
}; - 右键点击gruntfile.js,选择”Task Runner Explorer”
- 验证clean任务已经出现在“任务”节点下
- 右键点击clean任务,选择Run,一个命令行窗体显示,并执行定义的任务
- 在initConfig方法中,添加concat任务
Src属性定义了要链接的文件列表,dest属性定义了合并完成的目标文件,而all属性定义了在任何构建环境下,任务都将执行
module.exports = function (grunt) {
grunt.initConfig({
clean: ["wwwroot/lib/*", "temp/"],
concat: {
all: {
src: ['TypeScript/Tastes.js', 'TypeScript/Food.js'],
dest: 'temp/combined.js'
}
},
});
grunt.loadNpmTasks("grunt-contrib-clean");
}; - 添加jihit任务
jihit代码质量工具将会在temp目录下所有的js文件中运行
jshint: {
files: ['temp/*.js'],
options: {
'-W069': false,
}
} - 添加uglify任务
src定义了混淆的源文件列表,dest定义了目标文件
uglify: {
all: {
src: ['temp/combined.js'],
dest: 'wwwroot/lib/combined.min.js'
}
}, - 最后,调用grunt.loadNpmTasks()让上文定义的所有任务在Visual Studio中执行
- 保存文件,最终文件内容如下所示
module.exports = function (grunt) {
grunt.initConfig({
clean: ["wwwroot/lib/*", "temp/"],
concat: {
all: {
src: ['TypeScript/Tastes.js', 'TypeScript/Food.js'],
dest: 'temp/combined.js'
}
},
jshint: {
files: ['temp/*.js'],
options: {
'-W069': false,
}
},
uglify: {
all: {
src: ['temp/combined.js'],
dest: 'wwwroot/lib/combined.min.js'
}
},
});
grunt.loadNpmTasks("grunt-contrib-clean");
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
}; - 你会发现,上文定义的任务已经都出现在了Task Runner Explorer中
依次执行这些任务,
集成起来
使用grunt.registerTask方法来注册运行一系列指定顺序的任务,比如,运行上文中任务的顺序应该为clean->concat->jshint->uglify。在文件中添加以下代码,并且保持方法调用和loadNpmTasks调用时同级的
grunt.registerTask("all", ['clean', 'concat', 'jshint', 'uglify']);
现在你可以在Task Runner Explorer中找到一个名为all的别名任务,运行它即可顺序执行上文中的所有任务了
监测文件变化
Watch任务可以监视文件和目录的变化,并且在监测到变化后触发一系列任务,在initConfig方法中添加以下的代码来监视Typescript目录下的所有js文件的变化,并执行’all“任务
watch: {
files: ["TypeScript/*.js"],
tasks: ["all"]
}
添加一个loadNpmTask方法调用让任务显示在Task Runner Explorer中
grunt.loadNpmTasks('grunt-contrib-watch');
运行Watch任务,命令行窗体将处在等待状态,此时它监视着文件的变化,打开一个Typescript文件,添加任何内容,你就会发现它已经在工作了
与Visual Studio事件一起协作
你除了可以手动运行这些任务之外,你还可以把这些任务和Visual Studio事件绑定,当Visual Studio触发既定的事件后,自动运行定义的任务
在Task Runner Explorer中,右键点击watch任务,选择“Bindings->Project Open”,此时,当你打开项目的时候,watch任务将自动执行并且观测文件变化并执行上文中定义的一系列任务
使用Gulp
除了一些著名的不同以外,Gulp的配置文件和grunt的非常相似,下文中的例子对比grunt的示例但是使用gulp包和约定。
NPM 包的不同
与grunt一样,gulp定义也在ackage.json文件的devDependencies属性中,内容如下文所示,你也可以通过只能提示来更新到最近的版本号。
{
"version": "1.0.0",
"name": "GruntFromEmptyWebApp",
"private": true,
"devDependencies": {
"gulp": "3.8.11",
"gulp-clean": "0.3.1",
"gulp-jshint": "1.11.0",
"gulp-concat": "2.5.2",
"gulp-uglify":"1.2.0",
"gulp-rename": "1.2.2",
"gulp-watch": "4.2.4"
}
}
Gulpfile和Gruntfile示例的不同
取代gruntfile.js,添加一个命名为gulpfile.js的文件,在这个文件中,使用node.js的方法require()为下文中的几个变量赋值
var gulp = require('gulp');
var clean = require('gulp-clean');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var watch = require('gulp-watch');
在赋值语句下方,调用gulp的task方法,第一个参数是任务的名字的字符串表示方式,第二个参数是一个回调方法
gulp.task('default', function () {
// place code for your default task here
});
此时在Task Runner Explorer中已经存在一个命名为default的任务,虽然它是空的
在task方法的回调函数内部,使用方才定义的gulp执行我们需要的工作,首先定义一个clean任务
gulp.src('wwwroot/lib/*').pipe(clean());
Gulp流
gulp是一个包含src、pipe和dest方法的流式对象
- src()方法用来定义流从哪里来
- pipe()方法定义怎么重写流
- dest()方法定义流的输出
代码通常的模式如下文所示
gulp.src()
.pipe()
.pipe()
.pipe(dest());
src方法拿到初始的原始流文件,在一系列的pipe调用后执行对流的操作,最后通过dest()方法输出最终的结果,这种方式的优势是只有一个输入和一个输出,让任务执行的更快。
集成
下文是我们组织的一系列任务,将它定义为ALL,执行的任务和上文中grunt的例子是完全一样的
gulp.task("all", function () {
gulp.src('wwwroot/lib/*').pipe(clean());
gulp.src(['TypeScript/Tastes.js', 'TypeScript/Food.js'])
.pipe(concat("combined.js"))
.pipe(jshint())
.pipe(uglify())
.pipe(rename({
extname: '.min.js'
}))
.pipe(gulp.dest('wwwroot/lib'))
});
watch任务也和grunt的示例非常相似
gulp.task("watch", function () {
gulp.watch("TypeScript/*.js", ['all']);
});
使用同样的方式,在Task Runner Explorer中绑定Visual Studio事件,就可以让watch任务在项目打开时自动执行了。
乙烷
原文链接:http://docs.asp.net/en/latest/client-side/grunt-gulp.html
ASP.NET5之客户端开发:Grunt和Gulp构建工具在Visual Studio 2015中的高效的应用的更多相关文章
- Grunt和Gulp构建工具在Visual Studio 2015中的高效的应用
Grunt和Gulp构建工具在Visual Studio 2015中的高效的应用 Grunt和Gulp是Javascript世界里的用来做自动压缩.Typescript编译.代码质量lint工具.cs ...
- ASP.NET 5系列教程 (五):在Visual Studio 2015中使用Grunt、Bower开发Web程序
基于Visual Studio 2015,你可以: 方便的管理前端包,如jQuery, Bootstrap, 或Angular. 自动运行任务,如LESS.JavaScript压缩.JSLint.Ja ...
- [.net 面向对象程序设计进阶] (27) 团队开发利器(六)分布式版本控制系统Git——在Visual Studio 2015中使用Git
[.net 面向对象程序设计进阶] (26) 团队开发利器(六)分布式版本控制系统Git——在Visual Studio 2015中使用Git 本篇导读: 接上两篇,继续Git之旅 分布式版本控制系统 ...
- 在Visual Studio 2015 中添加SharePoint 2016 开发模板
前言 SharePoint 2016已经发布很久了,然而,默认安装VS2015以后,却没有SharePoint 2016的开发模板.其实问题很简单,和VS2012开发SharePoint 2013一样 ...
- Win10开发必备工具:Visual Studio 2015正式版下载
7月21日凌晨最新消息,面向大众用户的Visual Studio 2015集成开发工具正式版免费试用版已经推出.本文帮大家汇总一下简体中文社区版.专业版以及企业版在线安装版以及ISO离线安装镜像下载地 ...
- win8.1安装开发工具 vs2015 Visual Studio 2015 Preview Downloads
1.首先全新安装win8.1 略 破解激活.... 2.安装Visual Studio 2015 Visual Studio 2015 是免费的,不存在破解版本, 如果安装过程中存在问题,建议先把本文 ...
- Visual Studio 2015 前端开发工作流
Visual Studio 2015 CTP 5,全称为 Visual Studio 2015 Community Technology Preview 5,意为社区技术预览版,之前的版本为:Visu ...
- Visual Studio 2015速递(3)——ASP.NET 新特性
系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...
- 在 Visual Studio 2013 中使用 Grunt, Bower 和 NPM
在 Visual Studio 2015 中提供了对于 Grunt 和 Gulp 的内置支持,在 Visual Studio 2013 中怎么办呢?微软将 2015 中的特性作为几个独立的扩展发布出来 ...
随机推荐
- NSMapTable、NSHashTable与NSPointerArray的封装
NSMapTable.NSHashTable与NSPointerArray的封装 说明 NSMapTable对应NSDictionary:NSHashTable对应NSSet:NSPointerArr ...
- Python初学者第二十二天 函数进阶(1)
22day 1.函数命名空间: 2.函数作用域的查找顺序:LEGB locals->enclosing function ->globals ->_builtins_ a.local ...
- Python学习---IO的异步[twisted模块]
安装twisted模块 Linux: pip3 install twisted Window: a. http://www.lfd.uci.edu/~gohlke/pythonlibs/#twiste ...
- 使用MVC Razor生成格式良好的HTML Body作为邮件内容
PS: 实例化邮件类MailMessage有一个属性IsBodyHtml指示邮件正文是否是HTML格式. 我想利用Razor View的Model Binding / Rendering功能为我从AS ...
- 鼠标有但是U盘读取不出来怎么办
我今天就遇到了这个问题,搞了半天最后下了一个驱动人生,查看里面的回答才解决 就是把里面通用串行总控制器设置为隐藏文件可读之后选择把灰色的都删除就好了.具体可以在驱动人生里搜U盘不识别,之后就4,5步即 ...
- 【Alpha】Daily Scrum Meeting
一 博客集合贴 11月15日 [Alpha]Daily Scrum Meeting——blog1 11月18日 [Alpha]Daily Scrum Meeting——blog2 11月19日 [Al ...
- 一个查询ip地址的mysql数据库--ip2nation
http://ip2nation.com/ip2nation/Sample_Scripts/Country_Based_Redirect 并且已经集成进了laravel:https://github. ...
- ubuntu18.04 mariadb start失败
在Ubuntu 安装mariadb 再restart 后出现错误 journalctl -xe 发现 apparmor权限问题 AppArmor 是一款与SeLinux类似的安全框架/工具,其主要作用 ...
- HBase学习之路 (七)HBase 原理
系统架构 错误图解 这张图是有一个错误点:应该是每一个 RegionServer 就只有一个 HLog,而不是一个 Region 有一个 HLog. 正确图解 从HBase的架构图上可以看出,HBas ...
- ZOJ 4103 浙江省第16届大学生程序设计竞赛 D题 Traveler 构造
这个题,正赛的时候也没有过,不过其实已经有了正确的解法,可惜时间不多了,就没有去尝试. 题意是有n个点,i点能通向i-1,然后i和i*2.i*2+1互通. 请你构造一种路径从1能走完所有点,并且不重复 ...