以現(xiàn)在前端js激增的態(tài)勢,一個項目下來幾十個js文件輕輕松松 但是grunt的出現(xiàn)卻讓這些事情變得優(yōu)雅起來! grunt是一套前端自動化工具,一個基于nodeJs的命令行工具,一般用于: 對于其他用法,我還不太清楚,我們這里簡單介紹下grunt的壓縮、合并文件 初學(xué),有誤請包涵 準備階段1、nodeJs環(huán)境因為grunt是基于nodeJs的,所以首先各位需要安裝nodeJS環(huán)境,這塊我們便不管了 2、安裝grunt有了nodeJs環(huán)境后,我們便可以開始搞grunt了,因為我們可能在任何目錄下運行打包程序,所以我們需要安裝CLI npm install -g grunt-cli 這條命令將會把grunt命令植入系統(tǒng)路徑,這樣就能在任意目錄運行他,原因是 每次運行g(shù)runt時,它都會使用node的require查找本地是否安裝grunt,如果找到CLI便加載這個本地grunt庫 實例學(xué)習(xí):打包zepto一些東西說多了都是淚,直接先上實例吧,實例結(jié)束后再說其它的 ① package.json{ "name": "demo", "file": "zepto", "version": "0.1.0", "description": "demo", "license": "MIT", "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-jshint": "~0.6.3", "grunt-contrib-uglify": "~0.2.1", "grunt-contrib-requirejs": "~0.4.1", "grunt-contrib-copy": "~0.4.1", "grunt-contrib-clean": "~0.5.0", "grunt-strip": "~0.2.1" }, "dependencies": { "express": "3.x" } } ② Gruntfile.js完了我們需要在grunt目錄下執(zhí)行 npm install將相關(guān)的文件下載下來: $ cd d:
$ cd grunt 然后我們的目錄就會多一點東西: 多了很多東西,先別管事干什么的,我們后面都會用到,這個時候在目錄下新建src文件夾,并且搞一個zepto進去 然后在Gruntfile中新增以下代碼(先別管,增加再說) module.exports = function (grunt) { // 項目配置 grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.file %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, build: { src: 'src/<%=pkg.file %>.js', dest: 'dest/<%= pkg.file %>.min.js' } } }); // 加載提供"uglify"任務(wù)的插件 grunt.loadNpmTasks('grunt-contrib-uglify'); // 默認任務(wù) grunt.registerTask('default', ['uglify']); } 然后運行 grunt命令后 grunt 嗯嗯,多了一個文件,并且是壓縮的,不差?。?!第一步結(jié)束 認識Gruntdile與package.json不出意外,每一個gurnt都會需要這兩個文件,并且很可能就只有這兩個文件(復(fù)雜的情況有所不同) package.json這個文件用來存儲npm模塊的依賴項(比如我們的打包若是依賴requireJS的插件,這里就需要配置) Gruntfile這個文件尤其關(guān)鍵,他一般干兩件事情: Gruntfile一般由四個部分組成 module.exports = function (grunt) { //你的代碼 } 這個不用知道為什么,直接將代碼放入即可 ② 項目/任務(wù)配置 pkg: grunt.file.readJSON('package.json') 這里的 grunt.file.readJSON就會將我們的配置文件讀出,并且轉(zhuǎn)換為json對象 然后我們在后面的地方就可以采用pkg.XXX的方式訪問其中的數(shù)據(jù)了 uglify是一個插件的,我們在package依賴項進行了配置,這個時候我們?yōu)橄到y(tǒng)配置了一個任務(wù) ① 在src中找到zepto進行壓縮(具體名字在package中找到) 這個任務(wù)配置其實就是一個方法接口調(diào)用,按照規(guī)范來就好,暫時不予關(guān)注,內(nèi)幕后期來 grunt.loadNpmTasks('grunt-contrib-uglify'); 用于加載相關(guān)插件 最后注冊一個自定義任務(wù)(其實也是默認任務(wù)),所以我們下面的命令行是等效的: grunt == grunt uglify 至此,我們就簡單解析了一番grunt的整個操作,下面來合并文件的例子 合并文件合并文件依賴于grunt-contrib-concat插件,所以我們的package依賴項要新增一項 "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-jshint": "~0.6.3", "grunt-contrib-concat": "~0.3.0", "grunt-contrib-uglify": "~0.2.1", "grunt-contrib-requirejs": "~0.4.1", "grunt-contrib-copy": "~0.4.1", "grunt-contrib-clean": "~0.5.0", "grunt-strip": "~0.2.1" }, 然后再將代碼寫成這個樣子 module.exports = function (grunt) { // 項目配置 grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { separator: ';' }, dist: { src: ['src/zepto.js', 'src/underscore.js', 'src/backbone.js'], dest: 'dest/libs.js' } } }); grunt.loadNpmTasks('grunt-contrib-concat'); // 默認任務(wù) grunt.registerTask('default', ['concat']); } 運行后,神奇的一幕發(fā)生了: 三個文件被壓縮成了一個,但是沒有壓縮,所以,我們這里再加一步操作,將之壓縮后再合并 module.exports = function (grunt) { // 項目配置 grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { separator: ';' }, dist: { src: ['src/zepto.js', 'src/underscore.js', 'src/backbone.js'], dest: 'dest/libs.js' } }, uglify: { build: { src: 'dest/libs.js', dest: 'dest/libs.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-concat'); // 默認任務(wù) grunt.registerTask('default', ['concat', 'uglify']); } 我這里的做法是先合并形成一個libs,然后再將libs壓縮成libs.min.js 所以我們這里換個做法,先壓縮再合并,其實unglify已經(jīng)干了這些事情了 module.exports = function (grunt) { // 項目配置 grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { "my_target": { "files": { 'dest/libs.min.js': ['src/zepto.js', 'src/underscore.js', 'src/backbone.js'] } } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); // 默認任務(wù) grunt.registerTask('default', ['uglify']); } 所以,我們就暫時不去關(guān)注concat了 最后,今天時間不早了,我們最后研究下grunt配合require于是便結(jié)束今天的學(xué)習(xí)吧 合并requireJS管理的文件有了前面基礎(chǔ)后,我們來干一件平時很頭疼的事情,便是將require管理的所有js文件給壓縮了合并為一個文件 在main.js中新增代碼: require.config({ baseUrl: '', shim: { $: { exports: 'zepto' }, _: { exports: '_' }, B: { deps: [ '_', '$' ], exports: 'Backbone' } }, paths: { '$': 'src/zepto', '_': 'src/underscore', 'B': 'src/backbone' } }); requirejs(['B'], function (b) { }); 這樣的話運行會自動加載幾個文件,我們現(xiàn)在希望將之合并為一個libs.js該怎么干呢??? 我們這里使用自定義任務(wù)方法來做,因為我們好像沒有介紹他 要使用requireJS相關(guān)需要插件 grunt.loadNpmTasks('grunt-contrib-requirejs'); 因為我們以后可能存在配置文件存在各個項目文件的情況,所以我們這里將requireJs相關(guān)的配置放入gruntCfg.json中 這樣我們的package.json就沒有什么實際意義了: { "name": "demo", "version": "0.1.0", "description": "demo", "license": "MIT", "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-jshint": "~0.6.3", "grunt-contrib-concat": "~0.3.0", "grunt-contrib-uglify": "~0.2.1", "grunt-contrib-requirejs": "~0.4.1", "grunt-contrib-copy": "~0.4.1", "grunt-contrib-clean": "~0.5.0", "grunt-strip": "~0.2.1" }, "dependencies": { "express": "3.x" } } 我們這里設(shè)置的require相關(guān)的grunt配置文件如下(gruntCfg.json): { "requirejs": { "main": { "options": { "baseUrl": "", "paths": { "$": "src/zepto", "_": "src/underscore", "B": "src/backbone", "Test": "src/Test" }, "web": { "include": [ "$", "_", "B", "Test" ], "out": "dest/libs.js" } } } } } 這里我們要打包這些文件搞到dest的libs.js文件中,這個文件照做就行,最后核心代碼如下: module.exports = function (grunt) { grunt.loadNpmTasks('grunt-contrib-requirejs'); //為了介紹自定義任務(wù)搞了一個這個 grunt.registerTask('build', 'require demo', function () { //任務(wù)列表 var tasks = ['requirejs']; //源碼文件 var srcDir = 'src'; //目標文件 var destDir = 'dest'; //設(shè)置參數(shù) grunt.config.set('config', { srcDir: srcDir, destDir: destDir }); //設(shè)置requireJs的信息 var taskCfg = grunt.file.readJSON('gruntCfg.json'); var options = taskCfg.requirejs.main.options, platformCfg = options.web, includes = platformCfg.include, paths = options.paths; var pos = -1; var requireTask = taskCfg.requirejs; options.path = paths; options.out = platformCfg.out; options.include = includes; //運行任務(wù) grunt.task.run(tasks); grunt.config.set("requirejs", requireTask); }); } 搞完了運行就好:grunt build grunt build 最后發(fā)現(xiàn)葉小釵三字,我就放心了,安全?。。。。。?/p> 下集預(yù)告1 HTML文件打包2 樣式文件打包3 移動打包文件我們的開發(fā)版本與使用版本可能不在一個位置哦 4 分支處理不同分支打包 5 native包與HTML5包在HTML5嵌入webview的時代,我們當然存在一次打包既要形成網(wǎng)站文件也要形成app文件 6 分頻道打包當然可能存在分頻道分分支打包的情況 今日到此為止,待續(xù)...... |
|