使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目


Posted in Javascript onFebruary 15, 2016

Grunt 简介
Grunt是一款基于js和node.js的构建工具,由于这段时间node.js越来越火爆,grunt拥有丰富的开源社区支持,产生了很多插件。还有一些插件散落在node社区。构建是一个和宽泛的表述,传统理解就是编译、打包、复制,而今,随着技术越来越丰富,构建还包括对前端组件的预处理,比如sass、less预处理成css,css和js的压缩和合并。grunt的插件可以很好的支持这些新的构建概念,而且更为适合用开源技术堆砌的项目。 虽然Grunt更多的用于程序构建,但是本质上Grunt是一个用来解决重复劳动的任务运行工具。

Grunt入门
安装
下载安装Node.js。下载地址

检查安装和查看版本:

node -v
v0.10.25

安装grunt命令行工具grunt-cli,使用-g全局安装,这样可以在任何一个目录里使用了。下面这条命令会把 grunt 加入你的系统搜索路径中,所以在任何目录下都可以使用此命令。

npm install -g grunt-cli

需要注意的是在linux或mac下有时会报没有权限的错误,这时须在前面加一个sudo

sudo npm install grunt-cli -g

查看版本:

grunt ?version
grunt-cli v0.1.13

卸载。如果你在之前安装过全局的 Grunt,那么先删除它。

npm uninstall -g grunt

grunt-cli只是一个grunt的命令行界面,需要使用grunt及其插件,必须在项目的路径(通常是项目根目录下)下安装grunt模块本身即需要插件模块。每当grunt命令被执行时,它会通过nodejs的require命令在本地寻找已经安装的grunt。正因为如此,你可以在任何子目录下运行grunt命令。 如果cli找到了一个本地安装的grunt,它会加载这个 grunt 库,然后应用你在 GruntFile 中写好的配置, 然后执行相应的任务。

配置文件
package.json
package.json用来保存当前目录下所安装和需要的node模块有哪些,例如:

{
 "name": "my-project-name",
 "version": "0.1.0",
 "author": "Your Name",

 "devDependencies": {
 "grunt": "~0.4.1"
 }
}

可以手动创建这个文件,或者通过npm init命令,并按照提示完成package.json文件的创建。如果手动创建了package.json,只需通过npm install来下载和安装所需的模块。模块安装时,会保存在node_modules目录中。

如果想要在之后添加所需模块,使用下面这个命令,可以使得package.json文件得到同步更新

npm install <module> --save-dev

Gruntfile.js
这个文件的地位就像Makefile一样,是一个指导grunt进行任务的文件,其中需要配置各个插件模块所需的参数,以及加载插件,并定义任务。更多关于Gruntfile可以参考这里。建议读者对Gruntfile有个整体的理解再继续。

使用Grunt构建ASP.NET MVC
MSbuild
在使用grunt来构建.NET项目之前,必须先了解MSbuild。MSBuild是微软的用来构建程序的工具,目前VisualStudio已经全面使用MSbuild编译项目了。MSbuild由一个msbuild工具、一组编译或构建器程序和xml文件组成。实际上VisualStudio中的.sln和.csproj等项目文件就是一个msbuild能够认识的xml(下面称为msbuild配置文件),VisualStudio通过调用msbuild,由msbuild识别其中的参数和构建行为标识来完成构建工作。我们也可以自己通过命令行自己来调用msbuild。

在msbuild中有两个关键的概念:Task和Property。Task是msbuild能够直接作为目标来执行的入口,在执行msbuild的时候要么指向默认的Task,否则必须指定目标Task是什么。Property就是变量,就像程序中的变量可以影响程序执行一样,Property可以影响构建的行为。

VisualStudio产生msbuild配置文件其实非常复杂,表面上看只有没有多上行,但是它通过import,将一些预定义的配置文件导入到当前文件,使得无法全面的查看完整的配置文件,以至于无法找到关键的Task项。好在有一个工具可以用来帮助分析msbuild配置文件的结构。

另外,在调用msbuild的时候,可以通过命令行参数来覆盖默认的属性和任务,比如下面的调用表示,以”Rebuild”这个Task作为目标,并将Configuration属性设置为Debug:

msbuild ConsoleApplication1.csproj /target:Rebuild /property:Configuration=Debug

更多关于msbuild,请参考微软的文档

手动使用msbuild代替VisualStudio
以发布到本机为例,经过笔者在VS2012下的环境中测试,使用VS在调用msbuild时使用了如下关键的参数覆盖:

  • Configuration:Debug或者Release,相信使用VS的同学对此不会陌生
  • VisualStudioVersion:VS在安装的时候会将一些公用的,VisualStudio相关的,msbuild配置文件预先存在某个版本相关的地方,在VisualStudio生成项目文件时,会包含一个$VisualStudioVersion变量,这个变量会与路径结合指向这些预先准备好的配置文件。在2012下,需要将这个值设置为11.0
  • WarningLevel:编译时的告警级别
  • DeleteExistingFiles:发布功能使用到的是否删除已存在文件的选项
  • WebPublishMethod:发布方式,笔者常用的是FileSystem,即发布到本机或远程共享的某个目录
  • publishUrl:如果WebPublishMethod是FileSystem,这个值表示发布的磁盘路径

关键的任务:

  • Build:即VS中针对某个项目的编译功能
  • Rebuild:即VS中针对某个项目的重新编译功能
  • WebPublish:即VS针对某个项目的发布功能

至此,我们已经可以使用msbuild命令行来代替VS的一些构建动作了。由于本篇的重点是grunt,读者可以参见微软的说明,自己试验一下:

PS: MSbuild通常位于类似这样的目录下:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
使用grunt-msbuild调用msbuild
终于到了介绍本文的主角了:grunt-msbuild。这是一个个人开发的msbuild调用中间件。作为grunt的插件,经过笔者亲测,完全可以使用。结合其他的grunt插件,简化了笔者发布项目的过程。

你可以像下面这样将这个插件添加进项目的Gruntfile,实现自动发布:

msbuild: {
  fontend: {    
    src: ['Web.FontEnd/Web.FontEnd.csproj'],
    options: {
      projectConfiguration: 'Release',
      targets: ['WebPublish'],
      stdout: true,
      maxCpuCount: 4,
      buildParameters: {
        WarningLevel: 2,
  VisualStudioVersion: "11.0",
  DeleteExistingFiles: 'True',
  WebPublishMethod: 'FileSystem',
  publishUrl: [font_pwd]
      },
      verbosity: 'quiet'
    }
  }
}

上面的代码实现了,将Web.FontEnd.csproj项目在Release模式下通过FileSystem发布方式发布到font_pwd变量指代的目录下。 这里需要注意的是,可能需要根据自己的VS版本修改VisualStudioVersion参数,可以通过查看类似如下目录:C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0来检查。font_pwd是一个js变量,根据需要进行调整。

Grunt的完整配置就不给出了,主要是要知道这几个关键的参数设置。

在实际使用过程中DeleteExistingFiles这个参数似乎不起作用,所以可能需要另外再包含清空目标文件夹的任务。下面是实际任务运行时的部分截图:

使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目

Javascript 相关文章推荐
JS中style属性
Oct 11 Javascript
JavaScript中去掉数组中的重复值的实现方法
Aug 03 Javascript
Javascript中call与apply的学习笔记
Sep 22 Javascript
Lab.js初次使用笔记
Feb 28 Javascript
最简单的JavaScript图片轮播代码(两种方法)
Dec 18 Javascript
深入浅析JavaScript中的作用域和上下文
Mar 26 Javascript
JavaScript实战之菜单特效
Aug 16 Javascript
Vue 2.X的状态管理vuex记录详解
Mar 23 Javascript
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
May 26 Javascript
js实现Tab选项卡切换效果
Jul 17 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧滑动,右侧不动)
Jan 23 Javascript
基于JavaScript实现十五拼图代码实例
Apr 26 Javascript
JavaScript模版引擎的基本实现方法浅析
Feb 15 #Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
Feb 15 #Javascript
一道常被人轻视的web前端常见面试题(JS)
Feb 15 #Javascript
获取阴历(农历)和当前日期的js代码
Feb 15 #Javascript
极易被忽视的javascript面试题七问七答
Feb 15 #Javascript
在JavaScript中使用JSON数据
Feb 15 #Javascript
三分钟带你玩转jQuery.noConflict()
Feb 15 #Javascript
You might like
第九节--绑定
2006/11/16 PHP
apache2.2.4+mysql5.0.77+php5.2.8安装精简
2009/04/29 PHP
对text数据类型不支持代码页转换 从: 1252 到: 936
2011/04/23 PHP
php循环创建目录示例分享(php创建多级目录)
2014/03/04 PHP
PHP预定义变量9大超全局数组用法详解
2016/04/23 PHP
Yii编程开发常见调用技巧集锦
2016/07/15 PHP
深入Javascript函数、递归与闭包(执行环境、变量对象与作用域链)使用详解
2013/05/08 Javascript
JavaScript:Div层拖动效果实例代码
2013/08/06 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
js+ajax实现获取文件大小的方法
2015/12/08 Javascript
详解javascript实现瀑布流绝对式布局
2016/01/29 Javascript
ClearTimeout消除闪动实例代码
2016/02/29 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
2016/08/12 Javascript
利用D3.js实现最简单的柱状图示例代码
2016/12/09 Javascript
微信小程序 template模板详解及实例代码
2017/03/09 Javascript
前端图片懒加载(lazyload)的实现方法(提高用户体验)
2017/08/21 Javascript
node.js实现的装饰者模式示例
2017/09/06 Javascript
Python创建对称矩阵的方法示例【基于numpy模块】
2017/10/12 Python
python 3.7.0 下pillow安装方法
2018/08/27 Python
Python实现图片批量加入水印代码实例
2019/11/30 Python
opencv-python 读取图像并转换颜色空间实例
2019/12/09 Python
Python操作MySQL数据库实例详解【安装、连接、增删改查等】
2020/01/17 Python
python 窃取摄像头照片的实现示例
2021/01/08 Python
用python监控服务器的cpu,磁盘空间,内存,超过邮件报警
2021/01/29 Python
HTML5新增的标签和属性归纳总结
2018/05/02 HTML / CSS
canvas实现滑动验证的实现示例
2020/08/11 HTML / CSS
俄罗斯在线水暖商店:Perfecto.ru
2019/10/25 全球购物
环境科学专业研究生求职信
2013/10/02 职场文书
体育课课后反思
2014/04/24 职场文书
人事局接收函
2015/01/31 职场文书
小学生法制教育心得体会
2016/01/14 职场文书
2019年公司卫生管理制度样本
2019/08/21 职场文书
python实现自定义日志的具体方法
2021/05/28 Python
Python中OpenCV实现查找轮廓的实例
2021/06/08 Python
教你在 Java 中实现 Dijkstra 最短路算法的方法
2022/04/08 Java/Android
Mysql 一主多从的部署
2022/05/20 MySQL