前端工程化——構(gòu)建工具選型

注:文章源于2017年8月的一次內(nèi)部分享,部分?jǐn)?shù)據(jù)可能已經(jīng)過時翎卓。

一契邀、什么是前端工程化

前端工程化是依據(jù)業(yè)務(wù)特點,將前端開發(fā)的規(guī)范失暴、流程坯门、技術(shù)、工具逗扒、經(jīng)驗等形成規(guī)范并建立成一種標(biāo)準(zhǔn)的體系古戴。

二、為什么要前端工程化

實現(xiàn)前端工程化的目的簡單來說就是通過流程規(guī)范矩肩、自動化工具來提升前端的開發(fā)效率现恼、性能、質(zhì)量黍檩、多人協(xié)作能力以及開發(fā)體驗叉袍。

近幾年前端仍保持較高的速度發(fā)展,前端開發(fā)面臨著的流程刽酱、資源組織和協(xié)同開發(fā)等各方面的挑戰(zhàn)喳逛,所以建立前端工程化是各個團隊必經(jīng)的成長過程。

但由于每個公司棵里、每個團隊甚至每個項目都有自己的特點艺配,所以這里先暫時拋開規(guī)范、流程衍慎、技術(shù)這些主觀的東西转唉,從工具入手,聊聊工具的特性及適應(yīng)場景稳捆,從而找到最適合自己團隊項目的工程化方案赠法。

三、構(gòu)建工具

構(gòu)建工具的主要功能就是實現(xiàn)自動化處理乔夯,例如對代碼進行檢查砖织、預(yù)編譯、合并末荐、壓縮侧纯;生成雪碧圖、sourceMap甲脏、版本管理眶熬;運行單元測試妹笆、監(jiān)控等,當(dāng)然有的工具還提供模塊化娜氏、組件化的開發(fā)流程功能拳缠。

網(wǎng)上各類的構(gòu)建工具非常多,有家喻戶曉的 Grunt贸弥、Gulp窟坐、Webpack,也有各大公司團隊開源的構(gòu)建工具绵疲,這里通過 Github 的 Star 數(shù)量來簡單的對比下各個工具的流行度:

stars.png

如果把工具按類型分可以分為這三類:

  1. 基于任務(wù)運行的工具:
    Grunt哲鸳、Gulp
    它們會自動執(zhí)行指定的任務(wù),就像流水線盔憨,把資源放上去然后通過不同插件進行加工帕胆,它們包含活躍的社區(qū)屠阻,豐富的插件宿崭,能方便的打造各種工作流褐隆。

  2. 基于模塊化打包的工具:
    Browserify、Webpack驯用、rollup.js
    有過 Node.js 開發(fā)經(jīng)歷的應(yīng)該對模塊很熟悉,需要引用組件直接一個 require 就 OK儒老,這類工具就是這個模式蝴乔,還可以實現(xiàn)按需加載、異步加載模塊驮樊。

  3. 整合型工具:
    Yeoman薇正、FIS、jdf囚衔、Athena挖腰、cooking、weflow
    使用了多種技術(shù)棧實現(xiàn)的腳手架工具练湿,好處是即開即用猴仑,缺點就是它們約束了技術(shù)選型,并且學(xué)習(xí)成本相對較高肥哎。

四辽俗、構(gòu)建工具選型

在做選型的時候,我們往往會考慮以下幾個因素:

  1. 是否符合團隊的技術(shù)棧
  2. 是否符合項目需求
  3. 生態(tài)圈是否完善篡诽、社區(qū)是否活躍

還是排除 1崖飘、2 主觀的因素,我們在不同類型的工具中選擇幾個熱門(滿足因素3)杈女,也就是:Grunt朱浴、Gulp吊圾、Webpack、Yeoman 看看它們的工作流赊琳、優(yōu)劣點以及適用場景街夭。

1、Grunt & Gulp

工作流:
這兩款工具都是基于任務(wù)類型躏筏,所以它們的工作流是一致的:

gulp_workflow.png

可以看到它們打包的策略通常是 All in one板丽,最后頁面還是引用 css、img趁尼、js埃碱,開發(fā)流程與徒手開發(fā)相比并無差異。

特點與不足
Grunt
Grunt 是老牌的構(gòu)建工具酥泞,特點是配置驅(qū)動砚殿,你需要做的就是了解各種插件的功能,然后把配置整合到 Gruntfile.js 中芝囤,可以看下面的配置例子似炎,簡單直接:

module.exports = function(grunt) {
  grunt.initConfig({
    jshint: {
      files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
      options: {
        globals: {
          jQuery: true
        }
      }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['jshint']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('default', ['jshint']);
};

Grunt 缺點也是配置驅(qū)動,當(dāng)任務(wù)非常多的情況下悯姊,試圖用配置完成所有事簡直就是個災(zāi)難羡藐;再就是它的 I/O 操作也是個弊病,它的每一次任務(wù)都需要從磁盤中讀取文件悯许,處理完后再寫入到磁盤仆嗦,例如:我想對多個 less 進行預(yù)編譯、壓縮操作先壕,那么 Grunt 的操作就是:

讀取 less 文件 -> 編譯成 css -> 存儲到磁盤 -> 讀取 css -> 壓縮處理 -> 存儲到磁盤

這樣一來當(dāng)資源文件較多瘩扼,任務(wù)較復(fù)雜的時候性能就是個問題了。

Gulp
Gulp 特點是代碼驅(qū)動垃僚,寫任務(wù)就和寫普通的 Node.js 代碼一樣:

var gulp = require('gulp');
var pug = require('gulp-pug');
var less = require('gulp-less');
var minifyCSS = require('gulp-csso');

gulp.task('html', function(){
  return gulp.src('client/templates/*.pug')
    .pipe(pug())
    .pipe(gulp.dest('build/html'))
});

gulp.task('css', function(){
  return gulp.src('client/templates/*.less')
    .pipe(less())
    .pipe(minifyCSS())
    .pipe(gulp.dest('build/css'))
});

gulp.task('default', [ 'html', 'css' ]);

再一個對文件讀取是流式操作(Stream)集绰,也就是說一次 I/O 可以處理多個任務(wù),還是 less 的例子谆棺,Gulp 的流程就是:

讀取 less 文件 -> 編譯成 css -> 壓縮處理 -> 存儲到磁盤

Gulp 作為任務(wù)類型的工具沒有明顯的缺點倒慧,唯一的問題可能就是完成相同的任務(wù)它需要寫的代碼更多一些,所以除非是項目有歷史包袱(原有項目就是基于 Grunt 構(gòu)建)在 Grunt 與 Gulp 對比看來還是比較推薦 Gulp包券!

適用場景:
通過上面的介紹可以看出它們側(cè)重對整個過程的控制管理纫谅,實現(xiàn)簡單、對架構(gòu)無要求溅固、不改變開發(fā)模式付秕,所以非常適合前端、小型侍郭、需要快速啟動的項目询吴。

2掠河、Webpack
Webpack 是目前最熱門的前端資源模塊化管理和打包工具,還是先通過一張圖大致了解它的運行方式:

工作流

webpack_workflow.png

特點與不足
Webpack 的特點:

  1. 把一切都視為模塊:不管是 CSS猛计、JS唠摹、Image 還是 HTML 都可以互相引用,通過定義 entry.js奉瘤,對所有依賴的文件進行跟蹤勾拉,將各個模塊通過 loader 和 plugins 處理,然后打包在一起盗温。
  2. 按需加載:打包過程中 Webpack 通過 Code Splitting 功能將文件分為多個 chunks藕赞,還可以將重復(fù)的部分單獨提取出來作為 commonChunk,從而實現(xiàn)按需加載卖局。

Webpack 也是通過配置來實現(xiàn)管理斧蜕,與 Grunt 不同的時,它包含的許多自動化的黑盒操作所以配置起來會簡單很多(但遇到問題調(diào)試起來就很麻煩)砚偶,一個典型的配置如下:

module.exports = {
    //插件項
    plugins: [commonsPlugin],
    //頁面入口文件配置
    entry: {
        index : './src/js/page/index.js'
    },
    //入口文件輸出配置
    output: {
        path: 'dist/js/page',
        filename: '[name].js'
    },
    module: {
        //加載器配置
        loaders: [
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            { test: /\.js$/, loader: 'jsx-loader?harmony' },
            { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
        ]
    },
    //其它解決方案配置
    resolve: {
        root: '/Users/Bell/github/flux-example/src', //絕對路徑
        extensions: ['', '.js', '.json', '.scss'],
        alias: {
            AppStore : 'js/stores/AppStores.js',
            ActionType : 'js/actions/ActionType.js',
            AppAction : 'js/actions/AppAction.js'
        }
    }
};

Webpack 的不足:

  1. 上手比較難:官方文檔混亂批销、配置復(fù)雜、難以調(diào)試(Webpack2 已經(jīng)好了很多)對于新手而言需要經(jīng)歷踩坑的過程染坯;
  2. 對于 Server 端渲染的多頁應(yīng)用有點力不從心:Webpack 的最初設(shè)計就是針對 SPA均芽,所以在處理 Server 端渲染的多頁應(yīng)用時,不管你如何 chunk酒请,總不能真正達到按需加載的地步,往往要去考慮如何提取公共文件才能達到最優(yōu)狀態(tài)鸣个。

模塊化與組件化
提到 Webpack 就不得不說它的模塊化加載方式羞反,先來看下傳統(tǒng)的模塊化方式:

├── scripts/
│    ├── dropdown.js
│    ├── lazyload.js
│    ├── modal.js
│    └── slider.js
├── styles/
│    ├── button.less
│    ├── list.less
│    ├── modal.less
│    └── slider.less

傳統(tǒng)的模塊化基于單種編程語言,目的是為了解耦和重用囤萤,而因為前端本身的特點(需要三種編程語言配合)以及能力限制昼窗,所以不能實現(xiàn)跨資源加載也就難以實現(xiàn)組件化。

而 Webpack 打破的這種思維局限涛舍,它的 Require anything 的理念在實現(xiàn)模塊化的同時也能夠很方便實現(xiàn)組件化澄惊,借助 Webpack 就可以很輕松的實現(xiàn)這種代碼組織結(jié)構(gòu):

├──components/
│    ├── button/
│    │    ├── button.js
│    │    ├── button.less
│    │    ├── dropdwon.js
│    │    └── icon.png
│    ├── modal/
│    ├── slider/

一旦實現(xiàn)組件化,那么我們的項目開發(fā)方式和分工合作方式就可以升級富雅,可以實現(xiàn)分組件并行開發(fā)掸驱,也可以方便的引用其它項目使用的組件:

項目A

組件 開發(fā)人員
選項卡 小明
資訊列表 華生
走馬燈 諸葛
模態(tài)窗口 復(fù)用

項目B

組件 開發(fā)人員
選項卡 復(fù)用
按鈕 小迪
模態(tài)窗口 龍辰
上傳 老馬

So,可以說組件化才是目前提升大型項目多人團隊合作效率的最佳解決方案没佑!

適用場景:
綜上所述毕贼,Webpack 特別適合配合 React.js、Vue.js 構(gòu)建單頁面應(yīng)用以及需要多人合作的大型項目蛤奢,在規(guī)范流程都已約定好的情況下往往能極大的提升開發(fā)效率與開發(fā)體驗鬼癣。

OK陶贼,對于前端工程工具的介紹就到這里,希望能在大家做技術(shù)選型的時候給予一定的幫助待秃;接下來還會帶來 Gulp拜秧、Webpack 在實際工作應(yīng)用的詳細(xì)教程。

參考文獻

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嘲恍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子雄驹,更是在濱河造成了極大的恐慌佃牛,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件医舆,死亡現(xiàn)場離奇詭異俘侠,居然都是意外死亡,警方通過查閱死者的電腦和手機蔬将,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門爷速,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人霞怀,你說我怎么就攤上這事惫东。” “怎么了毙石?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵廉沮,是天一觀的道長。 經(jīng)常有香客問我徐矩,道長滞时,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任滤灯,我火速辦了婚禮坪稽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鳞骤。我一直安慰自己窒百,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布豫尽。 她就那樣靜靜地躺著贝咙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拂募。 梳的紋絲不亂的頭發(fā)上庭猩,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天窟她,我揣著相機與錄音,去河邊找鬼蔼水。 笑死震糖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的趴腋。 我是一名探鬼主播吊说,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼优炬!你這毒婦竟也來了颁井?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蠢护,失蹤者是張志新(化名)和其女友劉穎雅宾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葵硕,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡眉抬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了懈凹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜀变。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖介评,靈堂內(nèi)的尸體忽然破棺而出库北,到底是詐尸還是另有隱情,我是刑警寧澤们陆,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布寒瓦,位于F島的核電站,受9級特大地震影響棒掠,放射性物質(zhì)發(fā)生泄漏孵构。R本人自食惡果不足惜屁商,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一烟很、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜡镶,春花似錦雾袱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至望伦,卻和暖如春林说,著一層夾襖步出監(jiān)牢的瞬間煎殷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工腿箩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留豪直,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓珠移,卻偏偏與公主長得像弓乙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钧惧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容