构建工具将分为三块,Grunt,gulp,webpack,我们将先从Grunt说起。
自动构建工具的意义是将代码自动进行编译(如commonjs浏览器端的代码编译),合并(将多个js文件合并成一个会减少请求次数,提高效率),压缩,js语法检查,只要提前配置好,Grunt就会自动完成这些工作。
Grunt的很多实用功能都来自与插件,而我们需要使用的,大多数是来自于官方的插件,我们可以去Grunt官网去寻找,官方的插件都是以contrib开头的,并且在官网的插件列表中被标记了星号。
接下来,让我们自己创建一个Grunt项目。
首先,按照如下的目录结构去创建目录。
|- build----------构建生成的文件所在的文件夹
|- src------------源码文件夹
|- js---------------js源文件夹
|- css--------------css源文件夹
|- index.html-----页面文件
|- Gruntfile.js---grunt配置文件(注意首字母大写)
|- package.json---项目包配置文件
{
"name": "grunt_test",
"version": "1.0.0"
}
创建完目录之后,我们需要下载Grunt,首先需要全局安装grunt-cli,命令:npm install -g grunt-cli
只有安装了grunt-cli之后,才可以在命令行使用grunt。
接下来需要安装grunt,命令:npm install grunt --save-dev,安装grunt后,grunt才可以使用。
如果安装完grunt-cli与grunt后,在命令行输入grunt后,会提示
“Warning: Task "default" not found. Use --force to continue.”
如果你在命令行输入 grunt ,却出现了“不是内部或者外部命令”,可以看看这个博客。
这是正常的,因为你没有配置Gruntfile.js,Gruntfile.js是一个配置文件,只有拥有了配置文件之后,grunt才知道它要进行什么任务,配置文件分为三块,1.初始化插件配置 2.加载插件任务 3.注册构建任务
这是Gruntfile.js的配置文件
module.exports = function(grunt) {
//初始化配置grunt任务。
grunt.initConfig();
// 当任务执行时,加载对应的插件
grunt.loadNpmTasks();
// 注册执行的默认任务,第二个参数数组中包含的东西表示:执行默认任务需要依赖的东西
grunt.registerTask('default', []);
};
现在,我们来进行第一个任务,文件的合并。
首先,需要在npm下载合并任务的grunt插件
命令:npm install grunt-contrib-concat --save-dev
然后,去grunt的官网搜索contrib-concat这个插件,接着,会跳转到插件在npm的页面。按照页面的教程,去配置相应任务,加载相应插件,配置好后,应如下代码所示
module.exports = function(grunt) {
// Project configuration.
//初始化配置grunt任务。
grunt.initConfig({
//这是concat,合并文件的配置,对象的名字和插件的最后名字相同。
concat: {
options: {
//separator表示两个模块的连接符,为分号;
separator: ';',
},
dist: {
//src代表你要合并的多个文件
src: ['src/js/module1.js','src/js/module2.js'],
//dest代表合并好的文件输出的目录。
dest: 'build/build.js',
},
},
});
// 当任务执行时,加载对应的插件
//需要加载相应的插件
grunt.loadNpmTasks('grunt-contrib-concat');
// 注册执行的默认任务,第二个参数数组中包含的东西表示:执行默认任务需要依赖的东西
grunt.registerTask('default', []);
};
主要是grunt.initConfig中对于concat的任务配置,与grunt.loadNpmTasks中插件的加载。
配置好之后,在cmd窗口中输入:grunt 任务名 即:grunt concat
提示出现:Done 即完成了文件的合并。
文件的合并,我们已经执行完毕了,接下来,我们将执行文件的压缩。
还是先在npm下载压缩插件,npm i grunt-contrib-uglify --save-dev,然后去npm官网寻找该文件所在的网页,按照教程配置。
module.exports = function(grunt) {
//初始化配置grunt任务。
grunt.initConfig({
//这是concat,合并文件的配置,对象的名字和插件的最后名字相同。
concat: {
options: {
//separator表示两个模块的连接符,为分号;
separator: ';',
},
dist: {
//src代表你要合并的多个文件
src: ['src/js/module1.js','src/js/module2.js'],
//dest代表合并好的文件输出的目录。
dest: 'build/js/build.js',
},
},
uglify: {
my_target: {
//files中的key与value分别代表压缩后输出文件的目录与要压缩的文件
files: {
'build/js/build.min.js': ['build/js/build.js']
}
}
}
});
// 当任务执行时,加载对应的插件
//需要加载相应的插件
grunt.loadNpmTasks('grunt-contrib-concat');
//每增加一个功能,就要重新使用该方法加载一次函数。
grunt.loadNpmTasks('grunt-contrib-uglify');
// 注册执行的默认任务,第二个参数数组中包含的东西表示:执行默认任务需要依赖的东西
grunt.registerTask('default', []);
};
配置的东西还是grunt.initConfig中对于uglify的任务配置,但是要注意的是,每次使用一个新的功能,就要用这个函数加载相应的模块,grunt.loadNpmTasks,如这次需要调用 grunt.loadNpmTasks('grunt-contrib-uglify');
然后在命令行中输入 grunt uglify ,如果输出Done则代表压缩成功。
----------------------------------------------------------------------------------------------------------------------------
目前,我们已经配置了两个任务了,但是每次想执行该任务的时候,都需要单独的使用 grunt 任务名 来执行任务,这还只是两个任务,如果任务多了,岂不是很麻烦,所以,我们就需要在grunt.registerTask()这个方法中,去配置要执行的任务,比如这次需要合并与压缩文件,我们就可以这样配置 “grunt.registerTask('default', ["concat","uglify"]);”
当在命令行中输入grunt时,就会自动的执行数组中的任务了。具体代码如下
//当第二个参数数组中有任务名称是,在命令行使用grunt就会执行数组中的任务.
grunt.registerTask('default', ["concat","uglify"]);
在目前的grunt中的插件,只能支持es5的语法,es6是无法压缩的,所以,如果想压缩的话,需要先使用babel将js文件转换成es5的语法,在进行操作。
并且,grunt默认任务的执行,是同步的,即,任务顺序是合并,压缩时,执行完合并,才会执行压缩,如果中间某个环节出问题了(比如文件不存在)是不会报错的,而是接着执行接下来的步骤。
-----------------------------------------------------------------------------------------------------------------------------
接下里,继续增加一些模块的任务,先从js的语法检查开始吧。
下载模块 npm install grunt-contrib-jshint --save-dev
加载模块 grunt.loadNpmTasks('grunt-contrib-jshint');
新建一个文件.jshintrc 用来配置如何检查js语法,如,是否每行语句结束是否要添加分号。内容如下(里面注释需要删除)
{
"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"]
}
添加任务配置
jshint: {
options: {
//用来标识要使用那个语法检查的文件
jshintrc:".jshintrc"
},
//需要检查那些文件
all: ['Gruntfile.js',"src/js/*.js"]
}
最后添加到任务中即可,命令行运行grunt即可执行。
grunt.registerTask('default', ["jshint","concat","uglify"]);
----------------------------------------------------------------------------------------------------------------------------
接下来是css的压缩。
插件下载 npm install grunt-contrib-cssmin --save-dev
模块加载:grunt;
插件配置:
cssmin: {
options: {
mergeIntoShorthands: false,
roundingPrecision: -1
},
target: {
//合并压缩与一体,key/value代表出入目录文件与目标文件
files: {
'build/css/output.min.css': ["src/css/*.css"]
}
}
}
最后任务添加,grunt执行,就可以进行css的合并压缩。
----------------------------------------------------------------------------------------------------------------------------
最后是grunt的自动监听文件是否变化,如果变化则自动执行任务进行编译压缩等操作,从而实现真正的自动化。
首先还是要安装模块,watch 模块 npm install grunt-contrib-watch --save-dev
然后进行任务模块加载: grunt.loadNpmTasks('grunt-contrib-watch');
在进行任务的配置:
watch: {
scripts: {
//要监控的文件
files: ['src/js/*.js','src/css/*.css'],
//文件若是发生变化,进行的任务
tasks: ["jshint","concat","uglify","cssmin"],
//是否全局修改
//意:如果只动了css文件,不全局修改就只是执行cssmin这个任务
options: {
spawn: false,
},
},
}
然后在添加一个新的任务队列:
grunt.registerTask('default', ["jshint","concat","uglify","cssmin"]);
//如果运行下面的任务,则自动监听变化,上面的则不会,只是进行任务
grunt.registerTask('do-watch',["default","watch"]);
这时,在命令行窗口输入: grunt do-watch就是监听文件的变化了,从而实现了真正的自动化。
最后,我把全部的代码放上来
module.exports = function(grunt) {
//初始化配置grunt任务。
grunt.initConfig({
//这是concat,合并文件的配置,对象的名字和插件的最后名字相同。
concat: {
options: {
//separator表示两个模块的连接符,为分号;
separator: ';',
},
dist: {
//src代表你要合并的多个文件
src: ['src/js/module1.js','src/js/module2.js'],
//dest代表合并好的文件输出的目录。
dest: 'build/js/build.js',
},
},
uglify: {
my_target: {
//files中的key与value分别代表压缩后输出文件的目录与要压缩的文件
files: {
'build/js/build.min.js': ['build/js/build.js']
}
}
},
jshint: {
options: {
//用来标识要使用那个语法检查的文件
jshintrc:".jshintrc"
},
//需要检查那些文件
all: ['Gruntfile.js',"src/js/*.js"]
},
cssmin: {
options: {
mergeIntoShorthands: false,
roundingPrecision: -1
},
target: {
//合并压缩与一体,key/value代表出入目录文件与目标文件
files: {
'build/css/output.min.css': ["src/css/*.css"]
}
}
},
watch: {
scripts: {
//要监控的文件
files: ['src/js/*.js','src/css/*.css'],
//文件若是发生变化,进行的任务
tasks: ["jshint","concat","uglify","cssmin"],
//是否全局修改
//意:如果只动了css文件,不全局修改就只是执行cssmin这个任务
options: {
spawn: false,
},
},
},
});
// 当任务执行时,加载对应的插件
//文件合并 //需要加载相应的插件
grunt.loadNpmTasks('grunt-contrib-concat');
//文件压缩 //每增加一个功能,就要重新使用该方法加载一次函数。
grunt.loadNpmTasks('grunt-contrib-uglify');
//js语法检查
grunt.loadNpmTasks('grunt-contrib-jshint');
//css的合并压缩
grunt.loadNpmTasks('grunt-contrib-cssmin');
//自动监视文件是否变化。
grunt.loadNpmTasks('grunt-contrib-watch');
//当第二个参数数组中有任务名称是,在命令行使用grunt就会执行数组中的任务.
grunt.registerTask('default', ["jshint","concat","uglify","cssmin"]);
//如果运行下面的任务,则自动监听变化,上面的则不会,只是进行任务
grunt.registerTask('do-watch',["default","watch"]);
};
目前grunt就先到这里了,接下来的guip与webpack过两天就会更新。