title: 前端構建工具對比
toc: true
date: 2018-10-17 19:41:31
categories:css
tags:前端
前端技術發展之快,各類能夠提升開發效率的新思想和框架層出不窮。可是它們都有一個共同點:node
源代碼沒法直接運行,必須經過轉換後才能夠正常運行。webpack
構建就是作這件事情,將源代碼轉換成可執行的JavaScript、CSS、HTML代碼,包括以下內容:web
代碼轉換:將TypeScript編譯成JavaScript、將SCSS編譯成CSS等。typescript
文件優化:壓縮JavaScript、CSS、HTML代碼,壓縮合並圖片等。npm
代碼分割:提取多個頁面的公共代碼,提取首屏不須要執行部分的代碼讓其異步加載。json
模塊合併:在採用模塊化的項目裏會有不少個模塊和文件,須要經過構建功能將模塊分類合併成一個文件。gulp
自動刷新:監聽本地源代碼的變化,自動從新構建、刷新瀏覽器。瀏覽器
代碼校驗:在代碼被提交到倉庫前須要校驗代碼是否符合規範,以及單元測試是否經過。
自動發佈:更新代碼後,自動構建出線上發佈代碼並傳輸給發佈系統。
構建實際上是工程化、自動化思想在前端開發中的體現,將一系列流程用代碼去實現,讓代碼自動化地執行這一系列複雜的流程。構建爲前端開發注入了更大的活力,解放了咱們的生產力。
Npm是在安裝Node. js時附帶的包管理器,
Npm Script則是Npm內置的一個功能,容許在package.json文件裏面使用scripts字段定義腳本命令:
{ // ... "scripts": { "build": "node build.js", "dev": "node dev.js", "pub": "node build.js" } }
優勢:內置,無須安裝其餘依賴。
缺點:功能太簡單,雖然提供了pre和post兩個鉤子,但不能方便地管理多個任務之間的依賴。
Grunt至關於進化版的Npm Script,它的誕生實際上是爲了彌補Npm Script的不足。
Grunt有大量現成的插件封裝了常見的任務,
也能管理任務之間的依賴關係,自動化地執行依賴的任務,
每一個任務的具體執行代碼和依賴關係寫在配置文件Gruntfile.js
裏,
例如:
module.exports = function(grunt) { // 全部插件的配置信息 grunt.initConfig({ // uglify插件的配置信息 uglify: { app_task: { files: { 'build/app.min.js': ['lib/index.js', 'lib/test.js'] } } }, // watch插件的配置信息 watch: { another: { files: ['lib/*.js'], } } }); // 告訴Grunt咱們將使用這些插件 grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); // 告訴Grunt咱們在終端中啓動Grunt時須要執行哪些任務 grunt.registerTask('dev', ['uglify','watch']); };
在項目根目錄下執行命令grunt dev
,就會啓動JavaScript文件壓縮和自動刷新功能。
優勢:
靈活,它只負責執行咱們定義的任務;
大量的可複用插件封裝好了常見的構建任務。
缺點:
集成度不高,要寫不少配置後才能夠用,沒法作到開箱即用。
Gulp 是一個基於流的自動化構建工具。
除了能夠管理和執行任務,還支持監聽文件、讀寫文件。
Gulp被設計得很是簡單,
只經過下面5種方法就能夠支持幾乎全部構建場景:
Gulp的最大特色是引入了流的概念,
同時提供了一系列經常使用的插件去處理流,
流能夠在插件之間傳遞,大體使用以下:
// 引入 Gulp var gulp = require('gulp'); // 引入插件 var jshint = require('gulp-jshint'); var sass = require('gulp-sass'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); // 編譯SCSS任務 gulp.task('sass', function() { // 讀取文件,經過管道餵給插件 gulp.src('./scss/*.scss') // SCSS 插件將 scss 文件編譯成 CSS 文件 .pipe(sass()) // 輸出文件 .pipe(gulp.dest('./css')); }); // 合併壓縮JavaScript文件 gulp.task('scripts', function() { gulp.src('./js/*.js') .pipe(concat('all.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); // 監聽文件的變化 gulp.task('watch', function(){ // 當 scss 文件被編輯時執行 SCSS 任務 gulp.watch('./scss/*.scss', ['sass']); gulp.watch('./js/*.js', ['scripts']); });
優勢:好用又不失靈活,既能夠單獨完成構建,也能夠和其餘工具搭配使用。
缺點:集成度不高,要寫不少配置後才能夠用,沒法作到開箱即用。
能夠將Gulp看做Grunt的增強版。
相對於Grunt,Gulp增長了監聽文件、讀寫文件、流式處理的功能。
Fis3 是一個來自百度的優秀國產構建工具。
相對於Grunt、Gulp這些只提供了基本功能的工具,
Fis3集成了Web開發中的經常使用構建功能。
讀寫文件:經過fis.match讀文件,release配置文件的輸出路徑。
資源定位:解析文件之間的依賴關係和文件位置。
文件指紋:在經過useHash配置輸出文件時爲文件URL加上md5戳,來優化瀏覽器的緩存。
文件編譯:經過parser配置文件解析器作文件轉換,例如將ES6編譯成ES5。
壓縮資源:經過optimizer配置代碼壓縮方法。
圖片合併:經過spriter配置合併CSS裏導入的圖片到一個文件中,來減小HTTP請求數。
大體使用以下:
// 加md5 fis.match('*.{js,css,png}', { useHash: true }); // 經過fis3-parser-typescript插件可將TypeScript文件轉換成JavaScript文件 fis.match('*.ts', { parser: fis.plugin('typescript') }); // 對CSS進行雪碧圖合併 fis.match('*.css', { // 爲匹配到的文件分配屬性useSprite useSprite: true }); // 壓縮JavaScript fis.match('*.js', { optimizer: fis.plugin('uglify-js') }); // 壓縮CSS fis.match('*.css', { optimizer: fis.plugin('clean-css') }); // 壓縮圖片 fis.match('*.png', { optimizer: fis.plugin('png-compressor') });
優勢:集成了各類Web開發所需的構建功能,配置簡單、開箱即用。
缺點:目前官方已經再也不更新和維護,不支持最新版本的Node.js。
Fis3是一種專一於Web開發的完整解決方案,若是將Grunt、Gulp比做汽車的發動機,則能夠將Fis3比做一輛完整的汽車。
Webpack 是一個打包模塊化JavaScript的工具,
在Webpack裏一切文件皆模塊,
經過Loader
轉換文件,
經過Plugin
注入鉤子,
最後輸出由多個模塊組合成的文件。
Webpack專一於構建模塊化項目。
一切文件,如JavaScript、CSS、SCSS、圖片、模板,
對於Webpack來講都是一個個模塊,
這樣的好處是能清晰地描述各個模塊之間的依賴關係,以方便Webpack對模塊進行組合和打包。
通過Webpack的處理,最終會輸出瀏覽器能使用的靜態資源。
Webpack具備很大的靈活性,能配置處理文件的方式,使用方法大體以下:
module.exports = { // 全部模塊的入口,Webpack從入口開始遞歸解析出全部依賴的模塊 entry: './app.js', output: { // 將入口所依賴的全部模塊打包成一個文件bundle.js輸出 filename: 'bundle.js' } }
優勢:
缺點:
Rollup是一個和Webpack很相似但專一於ES6的模塊打包工具。
它的亮點在於,能針對ES6源碼進行Tree Shaking(搖樹優化),以去除那些已被定義但沒被使用的代碼並進行Scope Hoisting(做用域提高),以減少輸出文件的大小和提高運行性能。
然而Rollup的這些亮點隨後就被Webpack模仿和實現。
因爲Rollup的使用方法和Webpack差很少,因此這裏就不詳細介紹如何使用Rollup了。
它們的差異:
上面介紹的構建工具是按照它們誕生的時間排序的,
它們是時代的產物,側面反映出Web開發的發展趨勢,以下所述:
通過多年的發展,Webpack已經成爲構建工具中的首選,這是有緣由的: