優化你的Grunt構建
在前端開發的今天,如果沒用過Grunt或Gulp你還真就不好意思和人打招呼的(今天先說Grunt)。因為前端開發變得越來越復雜,前端工程化也越來越重要。當然,相信讀者都能快速通過Grunt完成自己的前端工作流(workflow),下面是一個常見的Gruntfile.js, 它也的確能很好地工作。
module.exports=function(grunt){ grunt.initConfig({ pkg:grunt.file.readJSON('package.json'), concat:{ dist:{ src:['src/js/jquery.js','src/js/index.js','src/js/main.js'], dest:'dist/build.js', } }, imagemin:{ options:{ cache:false }, dist:{ files:[{ expand:true, cwd:'src/', src:['**/*.{png,jpg,gif}'], dest:'dist/' }] } } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-imagemin'); grunt.registerTask('default',['concat','imagemin']); };
但隨著你的項目迭代,你很可能會加入更多的構建task,然后你的Gruntfile.js很可能會變成幾百行,甚至上千行的大文件,而且,通常在這個時候,你也很可能會遇到構建太慢的尷尬,簡單的一次文件修改要花費數秒,甚至更長的時間才能完成構建。這種體驗就好比在一個2G內存的電腦上,同時開著10多個Sublime在寫代碼一樣,影響工作效率不說,更影響心情。本文將與大家一起探討Grunt在以下兩方面的優化:
1. 瘦身Gruntfile.js
2. 減少構建任務時間
</div>Gruntfile.js瘦身
1. 使用load-grunt-tasks(https://www.npmjs.com/package/load-grunt-tasks)此grunt插件會根據package.json加載相應的Grunt任務,幫我們省去了手動加載的麻煩。
2. 使用load-grunt-config(https://www.npmjs.com/package/load-grunt-config),這時你的Gruntfile.js會變得非常簡單:
module.exports=function(grunt){ varpath=require('path'); require('load-grunt-config')(grunt,{ // Grunt任務配置目錄 configPath:path.join(process.cwd(),'grunt/config'), // 加載Grunt任務并初始化 loadGruntTasks:{ pattern:['grunt-*'], config:require('./package.json'), scope:'devDependencies' } }); };
減少構建任務時間
因為grunt任務是單進程串行執行,加上每個任務都會有文件IO,所以任務執行效率并不高(我們現在有項目一次JS修改變動的Grunt 執行花費甚至達到了10秒的級別,當然前端代碼文件多也是一個原因)。根據本人親身體驗,大于2S的構建時間,就能讓你在開發中感覺到中斷:文件修改保存后,馬上去刷新瀏覽器,是看不到文件修改效果的。所以減少構建時間非常有必要。
</div>1. 說到構建時間,首先就得知道我們每個構建任務花費的時間。這時有兩個插件可以使用:time-grunt(https://www.npmjs.com /package/time-grunt)和grunt-timer(https://www.npmjs.com/package/grunt- timer)。time-grunt在構建完成后,會給出每個任務的耗時及占總耗時的百分比。但如果有watch任務存在,是看不到這個時間統計結果的,這時我們可以用grunt-timer;
2. 另一個不得不提到的插件是grunt-newer(https://www.npmjs.com/package/grunt-newer)。有了這個插件,我們就可以做到文件更改后,增量更新,而不是對所有的文件去執行任務task。此插件的使用也是非常簡單,只需要在原來任務前加上newer:即可
watch:{ css:{ files:'src/sass/**/*.scss', //tasks: ['compass:dev'] }, js:{ files:'src/js/**/*.js', tasks:['newer:concat'] } }
3. 使用grunt-concurrent(https://www.npmjs.com/package/grunt-concurrent)或 grunt-parallel(https://www.npmjs.com/package/grunt-parallel)并行運行你的構建任務
4. 使用jit-grunt(https://www.npmjs.com/package/jit-grunt)按需加載你的Grunt任務。當然我們用下面的代碼,簡單地實現此功能:
grunt.registerTask('dev',[],function(){ grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-express-concat'); grunt.loadNpmTasks('grunt-compass'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-newer'); grunt.task.run( 'clean:dev', 'compass:dev', 'concat', 'watch' ); });
- 如何上面你都嘗試了,構建時間還是讓你無法接受,或許你應該試試Gulp(https://www.npmjs.com/package/gulp)