隨著(zhù)前端工程化的趨勢,產(chǎn)生了越來(lái)越多的構建工具,而其中比較優(yōu)秀的就是grunt,npm,gulp,今天我來(lái)說(shuō)說(shuō)這三者間的區別以及他們的優(yōu)缺點(diǎn).
相信一般前端開(kāi)發(fā)者選擇構建工具的時(shí)候,更多的是看個(gè)人習慣以及團隊的情況.相信這三個(gè)構建工具總有一個(gè)會(huì )適合你的,我們先來(lái)看看grunt.
grunt是目前社區最成熟,插件支持最多的一個(gè)構建工具,不過(guò)它的配置項之多也常常被人詬病.下面就一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)說(shuō)它的用法.
grunt運行之前需要全局安裝命令行工具,本地安裝grunt插件
npm install -g grunt-cli
// 包裝函數module.exports = function(grunt) { // 任務(wù)配置 grunt.initConfig({ concat: { foo: { files:{ 'dist/main.js': 'source/*.js' } } } }); // 加載連接文件插件 grunt.loadNpmTasks('grunt-contrib-concat'); // 測試合并任務(wù) grunt.registerTask('concatdemo', ['concat:foo']);};上面就是一個(gè)合并文件的例子,假如任務(wù)內的操作比較多的話(huà),配置文件就非常多,grunt適合對nodejs不是非常熟悉的情況下使用,而且自定義插件也非常方便,這個(gè)可以看我之前寫(xiě)的文章.
grunt在處理多個(gè)子功能的時(shí)候會(huì )頻繁的調用io來(lái)讀取文件,而且不支持任務(wù)模塊的重用,也就是說(shuō)不能添加任務(wù)的依賴(lài).不過(guò)入門(mén)非常容易,這些只是我自己的一些看法,也許最適合你的才是最好的,下面我們再來(lái)看看npm.
也許有些人會(huì )說(shuō)npm不是包管理工具嗎?怎么又成了構建工具了,其實(shí)它是可以當成構建工具來(lái)用的,奧秘就在package.json文件里的scripts屬性上.這里是可以定義當前模塊的一些構建功能的,比如當你開(kāi)發(fā)一個(gè)有點(diǎn)規模的模塊的時(shí)候,開(kāi)發(fā)與發(fā)布引用的文件其實(shí)是不一樣的,一般發(fā)布的時(shí)候都會(huì )提供壓縮版或者一些測試用例,下面以一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明
{ "scripts": { "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true", "build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js", "doc": "docco underscore.js" }, "devDependencies": { "docco": "0.6.x", "phantomjs": "1.9.0-1", "uglify-js": "2.4.x" }, }上面的這個(gè)配置片段是underscore類(lèi)庫的配置,可以看出上面的構建屬性有test,build,doc,這三個(gè)分別代表三個(gè)任務(wù),運行命令如下
npm run
npm run后跟任務(wù)名就可以,任務(wù)內容支持bash腳本,也支持npm模塊本身提供的命令行命令,像上面的uglifyjs本身就提供有命令行壓縮命令,運行npm run命令之前要保證devDependencies里的依賴(lài)模塊已經(jīng)安裝到本地,沒(méi)有的話(huà)可以使用npm install命令安裝.
最后要說(shuō)的是,任務(wù)的內容了可以是自定義模塊,比如可以像這樣的
"scripts": { "demo": "./demo.js" }demo.js
#!/usr/bin/env nodeconsole.log(__dirname);console.log(process.cwd());注意運行命令之前需要確保系統有執行demo.js的權限,可以使用
chmod 777 demo.js
打開(kāi)訪(fǎng)問(wèn)權限,然后我們運行
npm run demo
就會(huì )看到輸出當前運行根目錄內容,而且這里的js文件可以寫(xiě)很多自定義的東西.
最后要說(shuō)明下,npm最適用于類(lèi)linux系統,因為這些系統對命令支持非常友好,windows的話(huà)得安裝模擬*inux的命令行工具
npm一般用在個(gè)人項目里,對于團隊項目則不適用.最后說(shuō)下gulp.
gulp跟grunt一樣支持跨平臺,不同于grunt需要Gruntfile.js,gulp需要Gulpfile.js,最核心的不同之處在于,gulp是以流為核心的,而grunt是以配置加上文件io為核心的.
gulp是流為核心然后通過(guò)管道來(lái)輸入輸出各個(gè)子功能的內容以方便后續操作,這樣可以提高io訪(fǎng)問(wèn)效率,自定義插件方面要比grunt要求要高點(diǎn),下面以一個(gè)簡(jiǎn)單的例子看看它的用法.
運行gulp的系統要求
touch Gulpfile.js
npm install -g gulp
npm install gulp
var gulp = require('gulp'), uglify = require('gulp-uglify'), size = require('gulp-size');gulp.task('jsmin', function(){ return gulp .src('./app.js') .pipe(size()) .pipe(uglify()) .pipe(size()) .pipe(gulp.dest('dist/main'));});gulp是以src為開(kāi)始,里面傳遞任務(wù)需要的源文件,文件格式跟grunt相同,后面都是以pipe來(lái)傳輸前一步的輸出內容,最后可以輸出到一個(gè)目標文件內通過(guò)dest方法.
gulp-size是一個(gè)統計管道里面內容的大小的,上面是用它來(lái)顯示出壓縮前后的大小用來(lái)對比用的.
gulp跟grunt一樣也支持任務(wù)里包含多個(gè)子任務(wù),像這樣的
gulp.task('build', ['jshint', 'jsmin']); // 以 gulp build 命令來(lái)運行不過(guò)跟grunt不一樣的是,上面的多個(gè)子運任務(wù)是異步執行的,而grunt是同步執行的.
gulp也支持像模塊里的依賴(lài)注入,而且運行自己的任務(wù)之前它會(huì )保證依賴(lài)都運行完畢,像下面這樣的
gulp.task('test', ['jsmin'], function(){ return gulp .src('dist/main/*.js') .pipe(gulp.dest('build'));});上面的代碼功能是當壓縮完js之后,把壓縮之后的文件內容重新copy到一個(gè)新的地方.
也許gulp唯一的缺點(diǎn)就是社區插件沒(méi)grunt豐富,但是隨著(zhù)越來(lái)越多的人進(jìn)入gulp,相信這個(gè)也不是問(wèn)題.
看了上面三個(gè)構建工具的分析,大家都喜歡用哪一個(gè)呢,個(gè)人推薦用gulp,因為它代碼量少而且效率比grunt要高,不過(guò)還是那句老話(huà),適合自己的才是最好的.

掃碼關(guān)注w3ctech微信公眾號
聯(lián)系客服