【grunt第三彈】grunt在前端實際項目中的應用


前言

經過前兩次的學習,我們了解了grunt打包的一些基礎知識,對於壓縮幾個文件有了初步認識

但是實際項目中的應用往往不是那么簡單的,因為我們會有分支,我們也會有app版本Html5版本,更復雜的情況是我們有各個頻道,而且各個頻道是不同的團隊在開發

那么統一的一套打包工具如何滿足不同團隊的需求呢?

然后,我們本地聯調時候,仍然需要打包,但是打包的代碼有些時候卻不想要minify,這些功能都是實際項目重要用到的

我們這個時間化大力氣學習grunt打包一塊的知識是有絕對意義的,不然前端代碼合並一塊的難題仍然不可破,所以有心思在前端的朋友還是應該掌握一套前端自動化工具

我們繼續幾天的學習吧!!!

移動打包文件

其實,grunt本身具有這樣的功能,但是我們實際項目重會出現這種可能:

我們核心框架會有一套壓縮代碼,並且會在對應目錄生成文件用於發布,但是這個地方的權限對各個頻道團隊是不可見的

所以,我們在各個頻道的公共文件夾內應該將剛剛的文件給復制過去,這塊代碼其實很簡單,不需要任何新知識都能實現:

我們這里依舊采用昨天的require相關的代碼,但是一有個不同的地方就是,我們要同時在D盤的common文件夾中生成該文件

這個代碼其實比較簡單,這里我們先介紹一個新的插件copy

grunt-contrib-copy

該插件用於復制文件到你想要的文件夾處

grunt.initConfig({ copy: {
  main: {
    flatten: true,
    src: 'src/*.js',
    dest: 'dest/'
  }
}
});

這段代碼就會將src中的js文件搞到dest里面,並且新建src文件夾:

$ grunt copy
Running "copy:main" (copy) task
Copied 7 files

若是不想復制文件夾只要文件應該這樣干:

grunt.initConfig({ copy: {
  main: {
    flatten: true,
    //    filter: 'isFile',
    expand: true,
    src: 'src/**.js',
    dest: 'dest/'
  }
}
});

這塊完了,我們就來移動打包文件至D盤了

移動打包文件

這個時候代碼這樣寫就好(也許移動前我們還想將其文件夾里面的東西銷毀,暫時不考慮了)

module.exports = function (grunt) {

  grunt.initConfig({ copy: {
    main: {
      //      flatten: true,
      //      expand: true,
      src: 'dest/**.js',
      dest: 'd:/common/'
    }
  }
  });

  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-requirejs');

  grunt.registerTask('build', 'require demo', function () {

    //第一步,讀取配置信息
    var cfg = grunt.file.readJSON('cfg.json');
    cfg = cfg.requirejs;
    grunt.config.set('requirejs', { test: cfg });

    //第二步,設置參數
    grunt.log.debug('參數:' + JSON.stringify(grunt.config()));

    //第三步跑任務
    grunt.task.run(['requirejs']);

  });

  grunt.registerTask('default', 'test demo', ['build', 'copy']);

}
Running "build" task

Running "requirejs:test" (requirejs) task
>> Tracing dependencies for: d:/grunt/dest/libs.js
>> Uglifying file: d:/grunt/dest/libs.js
>> d:/grunt/dest/libs.js
>> ----------------
>> d:/grunt/src/zepto.js
>> d:/grunt/src/underscore.js
>> d:/grunt/src/backbone.js
>> d:/grunt/src/test01.js
>> d:/grunt/src/require.text.js
>> text!src/demo01.html

Running "copy:main" (copy) task
Copied 8 files

關於移動相關的知識點暫時介紹到這里,我們進入下一話題

分支/頻道處理

我們在實際項目重會遇到這種情況,我們一個主干分支上可能拉出很多分支完成不同的功能,而各個分支就有那么一點點不同,那么這個時候打包工具該怎么辦呢?

我們一般是這樣處理的:

① 首先全局只會有一個打包工具

② 其次每一個分支都會有一個gruntCfg.json的配置文件,存儲相關的打包信息

③ 每次打包時候便把響應的分支打印到各自的dest目錄里面

為了模擬這一情況我們將grunt打包相關的文件放到D盤的grunt目錄里面,並在D盤新建gruntDemo目錄

然后我們在gruntDemo中建立一個項目,並且為這個項目拉一個分支,比如現在項目是地demo01與demo02

現在文件結構如下:

D:\GRUNTDEMO
├─demo01
│  │  gruntCfg.json
│  │
│  └─src
│          backbone.js
│          require.js
│          require.text.js
│          test01.js
│          test02.js
│          underscore.js
│          zepto.js
│
└─demo02
    │  gruntCfg.json
    │
    └─src
            backbone.js
            require.js
            require.text.js
            test01.js
            test02.js
            underscore.js
            zepto.js

這個時候,要實現功能最好的方法就是寫自定義任務了,其它方案不好使,這個時候起配置文件也需要有一定修改,比如其中的路徑需要加入參數信息

{
  "requirejs": {
    "options": {
      "baseUrl": "<%= config.srcDir %>",
      "paths": {
        "$": "src/zepto",
        "_": "src/underscore",
        "B": "src/backbone",
        "test": "src/test01",
        "text": "src/require.text"

      },
      "include": [
        "$",
        "_",
        "B",
        "test",
        "text!src/demo01.html"
        ],
        "out": "<%= config.destDir %>/libs.js"
      }
  }
}

這個時候initConfig相關信息時候,首先得傳入path依賴的文件目錄,以及輸出的文件目錄

module.exports = function (grunt) {

  grunt.loadNpmTasks('grunt-contrib-requirejs');

  //channel為頻道名稱,project為項目名稱,這里對應gruntDemo,branch為其分支,默認與grunt目錄為平行關系,佛則package.json里面應該有配置信息
  grunt.registerTask('build', 'require demo', function (channel, project, branch) {

    var path = '../' + channel + '/' + project + branch;
    grunt.log.debug('path: ' + path);

    //第一步,讀取配置信息
    var cfg = grunt.file.readJSON(path + '/gruntCfg.json');
    cfg = cfg.requirejs;

    grunt.config.set('config', {
      srcDir: path,
      destDir: path + '/dest'
    });

    grunt.config.set('requirejs', { main: cfg });

    //第二步,設置參數
    grunt.log.debug('param: ' + JSON.stringify(grunt.config()));

    //第三步跑任務
    grunt.task.run(['requirejs']);

  });

  grunt.registerTask('default', 'test demo', ['build', 'copy']);

}

於是我們第一步工作成功了:

$ grunt build:gruntDemo:demo:02 --debug
Running "build:gruntDemo:demo:02" (build) task
[D] Task source: d:\grunt\Gruntfile.js
[D] path: ../gruntDemo/demo02
[D] param: {"config":{"srcDir":"../gruntDemo/demo02","destDir":"../gruntDemo/dem
o02/dest"},"requirejs":{"main":{"options":{"baseUrl":"../gruntDemo/demo02","path
s":{"$":"src/zepto","_":"src/underscore","B":"src/backbone","test":"src/test01",
"text":"src/require.text"},"include":["$","_","B","test","text!src/demo01.html"]
,"out":"../gruntDemo/demo02/dest/libs.js"}}}}

Running "requirejs:main" (requirejs) task
[D] Task source: d:\grunt\node_modules\grunt-contrib-requirejs\tasks\requirejs.j
s
>> Tracing dependencies for: d:/gruntDemo/demo02/dest/libs.js
>> Uglifying file: d:/gruntDemo/demo02/dest/libs.js
>> d:/gruntDemo/demo02/dest/libs.js
>> ----------------
>> d:/gruntDemo/demo02/src/zepto.js
>> d:/gruntDemo/demo02/src/underscore.js
>> d:/gruntDemo/demo02/src/backbone.js
>> d:/gruntDemo/demo02/src/test01.js
>> d:/gruntDemo/demo02/src/require.text.js
>> text!src/demo01.html

如果改變一下任務命令呢:

grunt build:gruntDemo:demo:01 --debug

結果證明也是沒有問題的,這個地方我就不貼出來了,各位自己去試試,我們分支處理一塊暫時到這里

頻道處理其實我們這里已經做了,第一個參數是頻道,第二個參數是項目,第三個參數為分支,所以頻道相關我們暫時就不說了

native與HTML5打包

最后讓我們來看看如何打包native文件,native文件的打包其實與打包HTML5的方式類似,只不過我們這里需要一點點配置,讓一個項目可以打包成不同的效果

仍然以上面demo01為例,他的配置文件可能就需要做一定調整:

{
    "requirejs": {
        "options": {
            "baseUrl": "<%= config.srcDir %>", 
            "paths": {
                "$": "src/zepto", 
                "_": "src/underscore", 
                "B": "src/backbone", 
                "test": "src/test01", 
                "text": "src/require.text"
            }, 
            "web": {
                "include": [
                    "$", 
                    "_", 
                    "B", 
                    "test"
                ], 
                "out": "<%= config.destDir %>/libs.js"
            }, 
            "app": {
                "include": [
                    "$", 
                    "_", 
                    "B", 
                    "test", 
                    "text!src/demo01.html"
                ], 
                "out": "<%= config.destDir %>/libs_app.js"
            }
        }
    }
}

這里為了表現一點web與native的不同,我特意將web中少包含一個text文件,具體還得各位項目中去實踐

如此一來,我們的代碼需要做些許調整:

module.exports = function (grunt) {

  grunt.loadNpmTasks('grunt-contrib-requirejs');

  //type 打包app包還是web包,channel為頻道名稱,project為項目名稱,這里對應gruntDemo,branch為其分支,默認與grunt目錄為平行關系,佛則package.json里面應該有配置信息
  grunt.registerTask('build', 'require demo', function (type, channel, project, branch) {

    var path = '../' + channel + '/' + project + branch;
    grunt.log.debug('path: ' + path);

    //第一步,讀取配置信息
    var cfg = grunt.file.readJSON(path + '/gruntCfg.json');
    cfg = cfg.requirejs.options;

    grunt.config.set('config', {
      srcDir: path,
      destDir: path + '/dest'
    });

    grunt.log.debug('param: ' + JSON.stringify(cfg));
    grunt.log.debug('param: ' + cfg[type]['include']);


    var taskCfg = {};
    taskCfg.options = {};
    taskCfg.options.baseUrl = cfg.baseUrl;
    taskCfg.options.paths = cfg.paths;
    taskCfg.options['include'] = cfg[type]['include'];
    taskCfg.options.out = cfg[type].out;


    grunt.config.set('requirejs', { main: taskCfg });

    //第二步,設置參數
    grunt.log.debug('param: ' + JSON.stringify(grunt.config()));

    //第三步跑任務
    grunt.task.run(['requirejs']);

  });

  grunt.registerTask('default', 'test demo', ['build', 'copy']);

}

於是便可以運行了!!!

$ grunt build:app:gruntDemo:demo:01 --debug
Running "build:app:gruntDemo:demo:01" (build) task
[D] Task source: d:\grunt\Gruntfile.js
[D] path: ../gruntDemo/demo01
[D] param: {"baseUrl":"<%= config.srcDir %>","paths":{"$":"src/zepto","_":"src/u
nderscore","B":"src/backbone","test":"src/test01","text":"src/require.text"},"we
b":{"include":["$","_","B","test"],"out":"<%= config.destDir %>/libs.js"},"app":
{"include":["$","_","B","test","text!src/demo01.html"],"out":"<%= config.destDir
 %>/libs_app.js"}}
[D] param: $,_,B,test,text!src/demo01.html
[D] param: {"config":{"srcDir":"../gruntDemo/demo01","destDir":"../gruntDemo/dem
o01/dest"},"requirejs":{"main":{"options":{"baseUrl":"../gruntDemo/demo01","path
s":{"$":"src/zepto","_":"src/underscore","B":"src/backbone","test":"src/test01",
"text":"src/require.text"},"include":["$","_","B","test","text!src/demo01.html"]
,"out":"../gruntDemo/demo01/dest/libs_app.js"}}}}

Running "requirejs:main" (requirejs) task
[D] Task source: d:\grunt\node_modules\grunt-contrib-requirejs\tasks\requirejs.j
s
>> Tracing dependencies for: d:/gruntDemo/demo01/dest/libs_app.js
>> Uglifying file: d:/gruntDemo/demo01/dest/libs_app.js
>> d:/gruntDemo/demo01/dest/libs_app.js
>> ----------------
>> d:/gruntDemo/demo01/src/zepto.js
>> d:/gruntDemo/demo01/src/underscore.js
>> d:/gruntDemo/demo01/src/backbone.js
>> d:/gruntDemo/demo01/src/test01.js
>> d:/gruntDemo/demo01/src/require.text.js
>> text!src/demo01.html

結語

我們這個星期花了三天時間一起學習了grunt打包相關的知識點,需要這些知識對您有用,搞這個東西還花費了不少心血呢!!!

若是文中有誤請一並提出,后續若是這塊有所得我們再一起總結吧

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM