前端構建工具對比


title: 前端構建工具對比
toc: true
date: 2018-10-17 19:41:31
categories:css

  • Web

tags:前端

  • 前端構建工具
  • grunt
  • gulp
  • webpack

前端技術發展之快,各類能夠提升開發效率的新思想和框架層出不窮。可是它們都有一個共同點:node

源代碼沒法直接運行,必須經過轉換後才能夠正常運行。webpack

構建就是作這件事情,將源代碼轉換成可執行的JavaScript、CSS、HTML代碼,包括以下內容:web

代碼轉換:將TypeScript編譯成JavaScript、將SCSS編譯成CSS等。typescript

文件優化:壓縮JavaScript、CSS、HTML代碼,壓縮合並圖片等。npm

代碼分割:提取多個頁面的公共代碼,提取首屏不須要執行部分的代碼讓其異步加載。json

模塊合併:在採用模塊化的項目裏會有不少個模塊和文件,須要經過構建功能將模塊分類合併成一個文件。gulp

自動刷新:監聽本地源代碼的變化,自動從新構建、刷新瀏覽器。瀏覽器

代碼校驗:在代碼被提交到倉庫前須要校驗代碼是否符合規範,以及單元測試是否經過。

自動發佈:更新代碼後,自動構建出線上發佈代碼並傳輸給發佈系統。

構建實際上是工程化、自動化思想在前端開發中的體現,將一系列流程用代碼去實現,讓代碼自動化地執行這一系列複雜的流程。構建爲前端開發注入了更大的活力,解放了咱們的生產力。

Npm Scripts

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

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 是一個基於流的自動化構建工具。

除了能夠管理和執行任務,還支持監聽文件、讀寫文件。

Gulp被設計得很是簡單,

只經過下面5種方法就能夠支持幾乎全部構建場景:

  • 經過gulp.task註冊一個任務
  • 經過gulp.run執行任務
  • 經過gulp.watch監聽文件的變化
  • 經過gulp.src讀取文件
  • 經過gulp.dest寫文件

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

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

Webpack 是一個打包模塊化JavaScript的工具,

在Webpack裏一切文件皆模塊,

經過Loader轉換文件,

經過Plugin注入鉤子,

最後輸出由多個模塊組合成的文件。

Webpack專一於構建模塊化項目。

Webpack

一切文件,如JavaScript、CSS、SCSS、圖片、模板,

對於Webpack來講都是一個個模塊,

這樣的好處是能清晰地描述各個模塊之間的依賴關係,以方便Webpack對模塊進行組合和打包。

通過Webpack的處理,最終會輸出瀏覽器能使用的靜態資源。

Webpack具備很大的靈活性,能配置處理文件的方式,使用方法大體以下:

module.exports = {
  // 全部模塊的入口,Webpack從入口開始遞歸解析出全部依賴的模塊
  entry: './app.js',
  output: {
    // 將入口所依賴的全部模塊打包成一個文件bundle.js輸出 
    filename: 'bundle.js'
  }
}

優勢

  • 專一於處理模塊化的項目,能作到開箱即用、一步到位
  • 可經過Plugin擴展,完整好用又不失靈活
  • 使用場景不侷限於Web開發
  • 社區龐大活躍,常常引入緊跟時代發展的新特性,能爲大多數場景找到已有的開源擴展
  • 良好的開發體驗。

缺點

  • 只能用於採用模塊化開發的項目。

Rollup

Rollup是一個和Webpack很相似但專一於ES6的模塊打包工具。

它的亮點在於,能針對ES6源碼進行Tree Shaking(搖樹優化),以去除那些已被定義但沒被使用的代碼並進行Scope Hoisting(做用域提高),以減少輸出文件的大小和提高運行性能。

然而Rollup的這些亮點隨後就被Webpack模仿和實現。

因爲Rollup的使用方法和Webpack差很少,因此這裏就不詳細介紹如何使用Rollup了。

它們的差異:

  • Rollup是在Webpack流行後出現的替代品
  • Rollup生態鏈還不完善,體驗不如Webpack
  • Rollup的功能不如Webpack完善,但其配置和使用更簡單
  • Rollup不支持Code Spliting,但好處是在打包出來的代碼中沒有Webpack那段模塊的加載、執行和緩存的代碼
  • Rollup在用於打包JavaScript庫時比Webpack更有優點,由於其打包出來的代碼更小、更快。但它的功能不夠完善,在不少場景下都找不到現成的解決方案。

爲何選擇Webpack

上面介紹的構建工具是按照它們誕生的時間排序的,

它們是時代的產物,側面反映出Web開發的發展趨勢,以下所述:

  • 在Npm Script和Grunt時代,Web開發要作的事情變多,流程複雜,自動化思想被引入,用於簡化流程
  • 在Gulp時代,開始出現一些新語言用於提升開發效率,流式處理思想的出現是爲了簡化文件轉換的流程,例如將ES5轉換成ES6
  • 在Webpack時代,因爲單頁應用的流行,網頁的功能和實現代碼變得複雜、龐大,Web開發向模塊化改進
  • 這些構建工具都有各自的定位和專一點,它們之間既能夠單獨完成任務,也能夠相互搭配來彌補各自的不足。在瞭解這些常見的構建工具後,咱們須要根據本身的需求去判斷應該如何選擇和搭配它們才能更好地知足本身的需求。

通過多年的發展,Webpack已經成爲構建工具中的首選,這是有緣由的:

  • 大多數團隊在開發新項目時會採用緊跟時代的技術,這些技術幾乎都會採用「模塊化+新語言+新框架」,Webpack能夠爲這些新項目提供一站式的解決方案
  • Webpack有良好的生態鏈和維護團隊,能提供良好的開發體驗並保證質量
  • Webpack被全世界大量的Web開發者使用和驗證,能找到各個層面所需的教程和經驗分享。

參考連接:http://www.javashuo.com/article/p-eqbopsgj-k.html

相關文章
相關標籤/搜索