注:文章源于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ù)量來簡單的對比下各個工具的流行度:
如果把工具按類型分可以分為這三類:
基于任務(wù)運行的工具:
Grunt哲鸳、Gulp
它們會自動執(zhí)行指定的任務(wù),就像流水線盔憨,把資源放上去然后通過不同插件進行加工帕胆,它們包含活躍的社區(qū)屠阻,豐富的插件宿崭,能方便的打造各種工作流褐隆。基于模塊化打包的工具:
Browserify、Webpack驯用、rollup.js
有過 Node.js 開發(fā)經(jīng)歷的應(yīng)該對模塊很熟悉,需要引用組件直接一個require
就 OK儒老,這類工具就是這個模式蝴乔,還可以實現(xiàn)按需加載、異步加載模塊驮樊。整合型工具:
Yeoman薇正、FIS、jdf囚衔、Athena挖腰、cooking、weflow
使用了多種技術(shù)棧實現(xiàn)的腳手架工具练湿,好處是即開即用猴仑,缺點就是它們約束了技術(shù)選型,并且學(xué)習(xí)成本相對較高肥哎。
四辽俗、構(gòu)建工具選型
在做選型的時候,我們往往會考慮以下幾個因素:
- 是否符合團隊的技術(shù)棧
- 是否符合項目需求
- 生態(tài)圈是否完善篡诽、社區(qū)是否活躍
還是排除 1崖飘、2 主觀的因素,我們在不同類型的工具中選擇幾個熱門(滿足因素3)杈女,也就是:Grunt朱浴、Gulp吊圾、Webpack、Yeoman 看看它們的工作流赊琳、優(yōu)劣點以及適用場景街夭。
1、Grunt & Gulp
工作流:
這兩款工具都是基于任務(wù)類型躏筏,所以它們的工作流是一致的:
可以看到它們打包的策略通常是 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 的特點:
- 把一切都視為模塊:不管是 CSS猛计、JS唠摹、Image 還是 HTML 都可以互相引用,通過定義 entry.js奉瘤,對所有依賴的文件進行跟蹤勾拉,將各個模塊通過 loader 和 plugins 處理,然后打包在一起盗温。
- 按需加載:打包過程中 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 的不足:
- 上手比較難:官方文檔混亂批销、配置復(fù)雜、難以調(diào)試(Webpack2 已經(jīng)好了很多)對于新手而言需要經(jīng)歷踩坑的過程染坯;
- 對于 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ì)教程。
參考文獻
- Gulp和Webpack對比 - 簡書
- 我們是如何做好前端工程化和靜態(tài)資源管理 | Aotu.io「凹凸實驗室」
- 前端構(gòu)建工具漫談章郁,fis3枉氮、webpack、rollup.js - Div.IO
- cooking - 更易上手的前端構(gòu)建工具
- GitHub - o2team/athena: O2前端流程工具
- webpack不適合多頁面應(yīng)用驱犹?你寫的插件還不夠多 - 簡書
- Gulp和Webpack對比 - 簡書
- 詳解前端模塊化工具-Webpack · Issue #21 · dwqs/blog · GitHub
- JavaScript構(gòu)建(編繹)系統(tǒng)大比拼:Grunt vs. Gulp vs. NPM | Sina App Engine Blog