一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

30分鐘學(xué)會使用grunt打包前端代碼

 昵稱597197 2016-01-13

以現(xiàn)在前端js激增的態(tài)勢,一個項目下來幾十個js文件輕輕松松
對于復(fù)雜一點的單頁應(yīng)用來說,文件上百簡直是家常便飯,那么這個時候我們的js文件應(yīng)該怎么處理呢?
另外,對于css文件,又該如何處理呢??
這些都是我們實際工作中要遇到的問題,比如我們現(xiàn)在框架使用zepto、backbone、underscore
我們要如何將他們合成一個libs文件,這都是令人頭疼的問題

但是grunt的出現(xiàn)卻讓這些事情變得優(yōu)雅起來!
簡單一鍵,打包結(jié)束,尼瑪不是不可能?。?/p>

grunt

是一套前端自動化工具,一個基于nodeJs的命令行工具,一般用于:
① 壓縮文件
② 合并文件
③ 簡單語法檢查

對于其他用法,我還不太清楚,我們這里簡單介紹下grunt的壓縮、合并文件

初學(xué),有誤請包涵

準備階段

1、nodeJs環(huán)境

因為grunt是基于nodeJs的,所以首先各位需要安裝nodeJS環(huán)境,這塊我們便不管了
http://www.cnblogs.com/yexiaochai/p/3527418.html

2、安裝grunt

有了nodeJs環(huán)境后,我們便可以開始搞grunt了,因為我們可能在任何目錄下運行打包程序,所以我們需要安裝CLI
官方推薦在全局安裝CLI(grunt的命令行接口)

npm install -g grunt-cli

這條命令將會把grunt命令植入系統(tǒng)路徑,這樣就能在任意目錄運行他,原因是

每次運行g(shù)runt時,它都會使用node的require查找本地是否安裝grunt,如果找到CLI便加載這個本地grunt庫
然后應(yīng)用我們項目中的GruntFile配置,并執(zhí)行任務(wù)
PS:這段先不要管,安裝完了往下看

實例學(xué)習(xí):打包zepto

一些東西說多了都是淚,直接先上實例吧,實例結(jié)束后再說其它的
首先在D盤新建一個項目(文件夾就好)
在里面新增兩個文件(不要問為什么,搞進去先)

① package.json

復(fù)制代碼
{
  "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"
  }
}
復(fù)制代碼

② Gruntfile.js

完了我們需要在grunt目錄下執(zhí)行 npm install將相關(guān)的文件下載下來:

$ cd d:
$ cd grunt

然后我們的目錄就會多一點東西:

多了很多東西,先別管事干什么的,我們后面都會用到,這個時候在目錄下新建src文件夾,并且搞一個zepto進去

然后在Gruntfile中新增以下代碼(先別管,增加再說)

復(fù)制代碼
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']);
}
復(fù)制代碼

然后運行 grunt命令后

grunt

嗯嗯,多了一個文件,并且是壓縮的,不差?。?!第一步結(jié)束

認識Gruntdile與package.json

不出意外,每一個gurnt都會需要這兩個文件,并且很可能就只有這兩個文件(復(fù)雜的情況有所不同)

package.json

這個文件用來存儲npm模塊的依賴項(比如我們的打包若是依賴requireJS的插件,這里就需要配置)
然后,我們會在里面配置一些不一樣的信息,比如我們上面的file,這些數(shù)據(jù)都會放到package中
對于package的靈活配置,我們會在后面提到

Gruntfile

這個文件尤其關(guān)鍵,他一般干兩件事情:
① 讀取package信息
② 插件加載、注冊任務(wù),運行任務(wù)(grunt對外的接口全部寫在這里面)

Gruntfile一般由四個部分組成
① 包裝函數(shù)
這個包裝函數(shù)沒什么東西,意思就是我們所有的代碼必須放到這個函數(shù)里面

module.exports = function (grunt) {
//你的代碼
}

這個不用知道為什么,直接將代碼放入即可

② 項目/任務(wù)配置
我們在Gruntfile一般第一個用到的就是initConfig方法配置依賴信息

pkg: grunt.file.readJSON('package.json')

這里的 grunt.file.readJSON就會將我們的配置文件讀出,并且轉(zhuǎn)換為json對象

然后我們在后面的地方就可以采用pkg.XXX的方式訪問其中的數(shù)據(jù)了
值得注意的是這里使用的是underscore模板引擎,所以你在這里可以寫很多東西

uglify是一個插件的,我們在package依賴項進行了配置,這個時候我們?yōu)橄到y(tǒng)配置了一個任務(wù)
uglify(壓縮),他會干這幾個事情:

① 在src中找到zepto進行壓縮(具體名字在package中找到)
② 找到dest目錄,沒有就新建,然后將壓縮文件搞進去
③ 在上面加幾個描述語言

這個任務(wù)配置其實就是一個方法接口調(diào)用,按照規(guī)范來就好,暫時不予關(guān)注,內(nèi)幕后期來
這里只是定義了相關(guān)參數(shù),但是并未加載實際函數(shù),所以后面馬上就有一句:

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

用于加載相關(guān)插件

最后注冊一個自定義任務(wù)(其實也是默認任務(wù)),所以我們下面的命令行是等效的:

grunt == grunt uglify

至此,我們就簡單解析了一番grunt的整個操作,下面來合并文件的例子

合并文件

合并文件依賴于grunt-contrib-concat插件,所以我們的package依賴項要新增一項

復(fù)制代碼
"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"
},
復(fù)制代碼

然后再將代碼寫成這個樣子

復(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'
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-concat');
  // 默認任務(wù)
  grunt.registerTask('default', ['concat']);
}
復(fù)制代碼

運行后,神奇的一幕發(fā)生了:

三個文件被壓縮成了一個,但是沒有壓縮,所以,我們這里再加一步操作,將之壓縮后再合并

復(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']);
}
復(fù)制代碼

我這里的做法是先合并形成一個libs,然后再將libs壓縮成libs.min.js

所以我們這里換個做法,先壓縮再合并,其實unglify已經(jīng)干了這些事情了

復(fù)制代碼
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']);
}
復(fù)制代碼

所以,我們就暫時不去關(guān)注concat了

最后,今天時間不早了,我們最后研究下grunt配合require于是便結(jié)束今天的學(xué)習(xí)吧

合并requireJS管理的文件

有了前面基礎(chǔ)后,我們來干一件平時很頭疼的事情,便是將require管理的所有js文件給壓縮了合并為一個文件
首先我們建立一個簡單的程序,里面使用了zepto、backbone、underscore(事實上我并未使用什么)

在main.js中新增代碼:

復(fù)制代碼
require.config({
 baseUrl: '',
 shim: {
  $: {
      exports: 'zepto'
  },
  _: {
   exports: '_'
  },
  B: {
   deps: [
    '_',
    '$'
     ],
   exports: 'Backbone'
  }
 },
 paths: {
  '$': 'src/zepto',
  '_': 'src/underscore',
  'B': 'src/backbone'
 }
});
requirejs(['B'], function (b) {
});
復(fù)制代碼

這樣的話運行會自動加載幾個文件,我們現(xiàn)在希望將之合并為一個libs.js該怎么干呢???

我們這里使用自定義任務(wù)方法來做,因為我們好像沒有介紹他

要使用requireJS相關(guān)需要插件 

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

因為我們以后可能存在配置文件存在各個項目文件的情況,所以我們這里將requireJs相關(guān)的配置放入gruntCfg.json中

這樣我們的package.json就沒有什么實際意義了:

復(fù)制代碼
{
  "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"
  }
}
復(fù)制代碼

我們這里設(shè)置的require相關(guān)的grunt配置文件如下(gruntCfg.json):

復(fù)制代碼
{
  "requirejs": {
    "main": {
      "options": {
        "baseUrl": "",
        "paths": {
          "$": "src/zepto",
          "_": "src/underscore",
          "B": "src/backbone",
          "Test": "src/Test"
        },
        "web": {
          "include": [
            "$",
            "_",
            "B",
            "Test"
          ],
          "out": "dest/libs.js"
        }
      }
    }
  }
}
復(fù)制代碼

這里我們要打包這些文件搞到dest的libs.js文件中,這個文件照做就行,最后核心代碼如下:

復(fù)制代碼
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);
  });
}
復(fù)制代碼

搞完了運行就好: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ù)......


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩欧美亚洲综合在线| 中文字幕亚洲精品乱码加勒比| 高清一区二区三区四区五区| 亚洲欧美日韩综合在线成成| 日韩偷拍精品一区二区三区| 免费亚洲黄色在线观看| 精品偷拍一区二区三区| 国产av精品一区二区| 女人精品内射国产99| 国产日韩欧美在线亚洲| 日韩一区二区三区18| 91日韩在线观看你懂的| 日韩成人h视频在线观看 | 国产一级内片内射免费看 | 久久大香蕉精品在线观看| 国产日韩久久精品一区| 欧美一区二区三区十区| 高清在线精品一区二区| 伊人国产精选免费观看在线视频| 亚洲国产精品久久综合网| 伊人天堂午夜精品草草网| 午夜福利黄片免费观看| 男人和女人干逼的视频| 五月天丁香婷婷狠狠爱| 日本一本不卡免费视频| 九九热在线视频精品免费| 国产精品日韩欧美第一页| 成人午夜在线视频观看| 黄色片一区二区三区高清| 亚洲国产日韩欧美三级| 国产精品夜色一区二区三区不卡| 精品丝袜一区二区三区性色| 亚洲中文字幕有码在线观看| 真实偷拍一区二区免费视频| 深夜视频成人在线观看| 高清不卡一卡二卡区在线| 精品人妻一区二区三区在线看| 午夜传媒视频免费在线观看| 亚洲中文在线观看小视频| 日韩中文字幕欧美亚洲| 日本av一区二区不卡|