代码: https://github.com/RyenToretto/grunt-gulp-webpack
环境: node 版本 > 0.8
特点:
自动化: 压缩、合并、编译等等操作,前提是 Gruntfile.js 文件配置好了
Gruntfile.js 或 Gruntfile.coffee,用来配置或定义任务(task)并加载Grunt插件的
grunt 插件: grunt 作为大脑,指挥插件们工作
contrib-官方维护的插件
项目结构:
1. 全局安装 grunt 脚手架 命令行接口 grunt-cli
sudo npm install -g grunt-cli
调用与 Gruntfile.js 在同一目录中 Grunt
2. 局部安装 grunt
sudo npm install --save-dev grunt
每次运行grunt 时,他就利用node提供的require()系统查找本地安装的 Grunt。
正是由于这一机制,你可以在项目的任意子目录中运行 grunt,更多详情请阅读源码
3. 编辑 Gruntfile.js
- 在下面列出的这个
Gruntfile.js中
package.json 文件中的项目元数据(metadata)被导入到 Grunt 配置中
grunt-contrib-uglify 插件中的 uglify 任务(task)被配置为压缩(minify)源码文件
并依据上述元数据动态生成一个文件头注释。
当在命令行中执行 grunt 命令时,uglify 任务将被默认执行。
commonJS 模块化语法 暴露
-
module.exports = function(grunt) { // 初始化配置 grunt 任务. grunt.initConfig({ }); // 当 grunt 执行时,要加载的插件。 // grunt.loadNpmTasks(\'\'); // 注册 构建任务 列表。 grunt.registerTask(\'default\', []); // 默认任务,依赖为 [] };
4. 加入 合并 js 的插件 grunt-contrib-concat
(1) sudo npm install --save-dev grunt-contrib-concat
(2) 修改 Gruntfile.js
-
module.exports = function(grunt) { // 初始化配置 grunt 任务. grunt.initConfig({ concat: { options: { separator: \';\', // 连接符, 两个 js 文件之间 以 ; 连接 }, // 选项 dist: { src: [\'src/js/*.js\'], // 要合并的 源文件 dest: \'dist/built.js\', // 输出到的 新文件 }, // 合并 }, // 执行任务的任务名 }); // 当 grunt 执行时,要加载的插件。 grunt.loadNpmTasks(\'grunt-contrib-concat\'); // 注册 构建任务 列表。 grunt.registerTask(\'default\', []); // 默认任务,依赖为 [] };
(3) 执行 concat 任务
grunt concat
(4) 科学的 Gruntfile.js打包路径:
(5) index.html 调用下 js 看看效果
-
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html" charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="shortcut icon" href="https://img-yunzhi.cdn.bcebos.com/yz-favicon.ico" /> <link rel="bookmark" href="https://img-yunzhi.cdn.bcebos.com/yz-favicon.ico" type="image/x-icon" /> <title>自动化构建 - grunt</title> <script type="text/javascript" src="./static/js/fastclick.js"></script> </head> <body> <div id="app"></div> <script type="text/javascript"> if (\'addEventListener\' in document) { document.addEventListener(\'DOMContentLoaded\', function() { FastClick.attach(document.body); }, false); } if(!window.Promise) { document.writeln(\'<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"\'+\'>\'+\'<\'+\'/\'+\'script>\'); } /* 解决点击响应延时 0.3s 问题 */ </script> <script type="text/javascript" src="./build/js/build.js"></script> </body> </html>
5. 加入 压缩 js 的插件 grunt-contrib-uglify , 注册自动化任务数组
(1) sudo npm install --save-dev grunt-contrib-uglify
(2) 修改 Gruntfile.js
-
module.exports = function(grunt) { // 初始化配置 grunt 任务. grunt.initConfig({ pkg: grunt.file.readJSON(\'package.json\'), concat: { options: { separator: \';\', // 连接符, 两个 js 文件之间 以 ; 连接 }, // 选项 dist: { src: [\'src/js/*.js\'], // 要合并的 源文件 dest: \'build/js/build.js\', // 输出到的 新文件 }, // 合并 }, // concat 执行 合并任务 的任务名 uglify: { options: { // 压缩文件的 顶部注释 banner: \'/*! <%= pkg.name %> - v<%= pkg.version %> - \' + \'<%= grunt.template.today("yyyy-mm-dd") %> */\' }, build: { files: { \'build/js/build.min.js\': [\'build/js/build.js\'] } } } // uglify 执行 压缩任务 的任务名 }); // 当 grunt 执行时,要加载的插件。 grunt.loadNpmTasks(\'grunt-contrib-concat\'); grunt.loadNpmTasks(\'grunt-contrib-uglify\'); // 注册 构建任务 列表。 grunt.registerTask(\'default\', [ \'concat\', \'uglify\' ]); // 默认任务,依赖为 [], 执行 \'grunt default\' / \'grunt\' 后,会顺序执行数组里的任务 };
(3) 执行 grunt
6. 默认任务的 数组,会同步,顺序执行,所以先后顺序很重要
7. 加入 js-hint 语法检查插件
(1) sudo npm install --save-dev grunt-contrib-jshint
(2) 创建并配置 .jshintrc 文件
-
{ "curly": true, "eqeqeq": true, "eqnull": true, "expr": true, "immed": true, "newcap": true, "noempty": true, "noarg": true, "regexp": true, "browser": true, "devel": true, "node": true, "boss": false, "undef": true, "asi": false, "predef": [ "define", "BMap", "angular", "BMAP_STATUS_SUCCESS"] }
(3) 配置 Gruntfile.js
-
module.exports = function(grunt) { // 初始化配置 grunt 任务. grunt.initConfig({ pkg: grunt.file.readJSON(\'package.json\'), concat: { options: { separator: \';\', // 连接符, 两个 js 文件之间 以 ; 连接 }, // 选项 dist: { src: [\'src/js/*.js\'], // 要合并的 源文件 dest: \'build/js/build.js\', // 输出到的 新文件 }, // 合并 }, // concat 执行 合并任务 的任务名 uglify: { options: { // 压缩文件的 顶部注释 banner: \'/*! <%= pkg.name %> - v<%= pkg.version %> - \' + \'<%= grunt.template.today("yyyy-mm-dd") %> */\' }, build: { files: { \'build/js/build.min.js\': [\'build/js/build.js\'] } } }, // uglify 执行 压缩任务 的任务名 jshint : { options: { jshintrc : \'.jshintrc\' //指定配置文件 }, build : [\'Gruntfile.js\', \'src/js/*.js\'] //指定检查的文件 }, }); // 当 grunt 执行时,要加载的插件。 grunt.loadNpmTasks(\'grunt-contrib-concat\'); grunt.loadNpmTasks(\'grunt-contrib-uglify\'); grunt.loadNpmTasks(\'grunt-contrib-jshint\'); // 注册 构建任务 列表。 grunt.registerTask(\'default\', [ \'concat\', \'uglify\', \'jshint\' ]); // 默认任务,依赖为 [], 执行 \'grunt default\' / \'grunt\' 后,会顺序执行数组里的任务 };
(4) 构建
grunt
8. 加入 合并压缩 css 的插件
(1) sudo npm install --save-dev grunt-contrib-cssmin
(2) 配置 Gruntfile.js
-
module.exports = function(grunt) { // 初始化配置 grunt 任务. grunt.initConfig({ pkg: grunt.file.readJSON(\'package.json\'), concat: { options: { separator: \';\', // 连接符, 两个 js 文件之间 以 ; 连接 }, // 选项 dist: { src: [\'src/js/*.js\'], // 要合并的 源文件 dest: \'build/js/build.js\', // 输出到的 新文件 }, // 合并 }, // concat 执行 合并任务 的任务名 uglify: { options: { // 压缩文件的 顶部注释 banner: \'/*! <%= pkg.name %> - v<%= pkg.version %> - \' + \'<%= grunt.template.today("yyyy-mm-dd") %> */\' }, build: { files: { \'build/js/build.min.js\': [\'build/js/build.js\'] } } }, // uglify 执行 压缩任务 的任务名 jshint : { options: { jshintrc : \'.jshintrc\' //指定配置文件 }, build : [\'Gruntfile.js\', \'src/js/*.js\'] //指定检查的文件 }, // 语法检查插件 cssmin: { options: { shorthandCompacting: false, roundingPrecision: -1 }, build: { files: { \'build/css/build.min.css\': [\'src/css/*.css\'] } } } // css 合并压缩插件 }); // 当 grunt 执行时,要加载的插件。 grunt.loadNpmTasks(\'grunt-contrib-concat\'); grunt.loadNpmTasks(\'grunt-contrib-uglify\'); grunt.loadNpmTasks(\'grunt-contrib-jshint\'); grunt.loadNpmTasks(\'grunt-contrib-cssmin\'); // 注册 构建任务 列表。 grunt.registerTask(\'default\', [ \'concat\', \'uglify\', \'jshint\', \'cssmin\' ]); // 默认任务,依赖为 [], 执行 \'grunt default\' / \'grunt\' 后,会顺序执行数组里的任务 };
(3) 构建
grunt
9. 实现 watch 监视文件修改任务,实现自动打包编译
(1) sudo npm install --save-dev grunt-contrib-watch
(2) 修改 Gruntfile.js
-
module.exports = function(grunt) { // 初始化配置 grunt 任务. grunt.initConfig({ pkg: grunt.file.readJSON(\'package.json\'), concat: { options: { separator: \';\', // 连接符, 两个 js 文件之间 以 ; 连接 }, // 选项 dist: { src: [\'src/js/*.js\'], // 要合并的 源文件 dest: \'build/js/build.js\', // 输出到的 新文件 }, // 合并 }, // concat 执行 合并任务 的任务名 uglify: { options: { // 压缩文件的 顶部注释 banner: \'/*! <%= pkg.name %> - v<%= pkg.version %> - \' + \'<%= grunt.template.today("yyyy-mm-dd") %> */\' }, build: { files: { \'build/js/build.min.js\': [\'build/js/build.js\'] } } }, // uglify 执行 压缩任务 的任务名 jshint : { options: { jshintrc : \'.jshintrc\' //指定配置文件 }, build : [\'Gruntfile.js\', \'src/js/*.js\'] //指定检查的文件 }, // 语法检查插件 cssmin: { options: { shorthandCompacting: false, roundingPrecision: -1 }, build: { files: { \'build/css/build.min.css\': [\'src/css/*.css\'] } } }, // css 合并压缩插件 watch : { scripts : { files : [\'src/js/*.js\', \'src/css/*.css\'], tasks : [\'concat\', \'jshint\', \'uglify\', \'cssmin\'], options : {spawn : false}//增量更新---全量更新 } } }); // 当 grunt 执行时,要加载的插件。 grunt.loadNpmTasks(\'grunt-contrib-concat\'); grunt.loadNpmTasks(\'grunt-contrib-uglify\'); grunt.loadNpmTasks(\'grunt-contrib-jshint\'); grunt.loadNpmTasks(\'grunt-contrib-cssmin\'); grunt.loadNpmTasks(\'grunt-contrib-watch\'); // 注册 构建任务 列表。 grunt.registerTask(\'default\', [ \'concat\', \'uglify\', \'jshint\', \'cssmin\' ]); // 默认任务,依赖为 [], 执行 \'grunt default\' / \'grunt\' 后,会顺序执行数组里的任务 grunt.registerTask(\'build\', [\'default\']); grunt.registerTask(\'dev\', [\'default\', \'watch\']); };
(3) grunt dev