分享个人 Full-Stack JavaScript 项目开发经验
Grunt 不是前端项目构建工具的唯一选择,但它拥有庞大的插件生态圈,是一个成熟的构建工具,这也意味着 Grunt 不会有频繁的版本更新。Bootstrap 的源码也使用 Grunt 构建,所以如果你前端项目是基于 Bootstrap 的,那么 Grunt 或许是最好的选择。Grunt 和 Grunt 插件基于 Node.js 环境运行,如果你尚未配置好 Node.js,可参考Node.js环境安装。下面介绍 Grunt 的安装及常用插件的选择:
把 grunt-cli 安装到全局环境,以后就可以在任何目录下执行 grunt 命令了,它会调用与 Gruntfile 同一目录中的 Grunt。
npm install grunt-cli -g
初始化 npm 项目,填写项目名称、版本、主入口文件、脚本命令定义等。
npm init
本地安装 Grunt
yarn add grunt --dev
在前端项目构建过程中,可能会遇到:
以上是前端项目开发管理的常规任务,Grunt 都可以帮我们自动化完成,最后输入几条命令即可。这些任务对应的 Grunt 插件如下:
安装以上插件:
yarn add --dev grunt-contrib-imagemin
yarn add --dev grunt-contrib-connect
yarn add --dev grunt-contrib-watch
yarn add --dev grunt-contrib-compass
yarn add --dev grunt-postcss
yarn add --dev autoprefixer
yarn add --dev grunt-contrib-cssmin
yarn add --dev grunt-contrib-jshint
yarn add --dev grunt-contrib-qunit
yarn add --dev grunt-contrib-uglify
yarn add --dev grunt-contrib-concat
yarn add --dev webpack
yarn add --dev grunt-webpack
注意:grunt-webpack 是依赖于 webpack 的。
Gruntfile 是用于配置任务逻辑的文件。它支持使用 Javascript 或 CoffeeScript 文件,一般使用 Gruntfile.js。它需要放在和 package.json 文件同一目录层级(根目录)。它包括"wrapper" 函数、项目和任务配置、加载 Grunt 插件和任务、自定义任务四部分内容。
module.exports = function(grunt) {
// 项目与任务配置、加载 grunt 插件和任务、自定义任务
};
项目和任务的配置通过 grunt.initConfig({...}) 函数实现,它接收一个配置对象作为参数。大多数插件的任务要求它的配置使用同名属性。配置上述插件的格式类似于:
grunt.initConfig({
imagemin: {...},
connect: {...},
watch: {...},
compass: {...},
postcss: {...},
cssmin: {...},
jshist: {...},
qunit: {...},
uglify: {...},
concat: {...},
webpack: {...}
});
插件安装成功后,需要调用 grunt.loadNpmTask('...') 载入插件和任务。
grunt.loadNpmTask('grunt-contrib-imagemin');
// ...
grunt.loadNpmTask('grunt-webpack');
如果你不想逐个载入,可以使用 load-grunt-tasks 插件以自动方式载入。它的原理是读取 package.json 的 dependencies、devDependencies、peerDependencies、optionalDependencies 字段,然后对应加载 node_modules 目录下的插件。安装:
yarn add --dev load-grunt-tasks
使用和默认配置如下:
require('load-grunt-tasks')(grunt, {
pattern: ['grunt-*', '@*/grunt-*'],
config: './package.json',
scope: ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'],
requireResolution: false
});
使用默认配置时候可以省略第二个参数,即:
require('load-grunt-tasks')(grunt);
可使用多个 grunt.registerTask() 定义一系列任务,如:
grunt.registerTask('test', ['imagemin:front', 'concat']);
上面定义了任务 test,它代表先执行配置中 imagemin 任务的 front 目标,然后执行配置中的 concat 任务。执行指令:
grunt test
一般我们会设置一个命名为 default 的默认任务,使可以直接用 grunt 指令执行,无需指定任务名称。
如果这种任务定义方式不能满足项目的需求,我们还可以自定义具体的任务操作,如:
grunt.registerTask('test', function () {
grunt.task.run(['imagemin:front', 'concat']);
// 其它操作...
});
Gruntfile 中的路径等具体的重复配置信息可以保存在一个外部 json 或 js 文件中,然后使用 grunt.file.readJSON() 或 require() 方式读取并使用。了解更多 Grunt API 说明,请点击这里。