如何看待 Grunt、Gulp 和 Webpack

? 相信小伙伴們不僅聽(tīng)說(shuō)過(guò) Gulp 和 webpack ,還聽(tīng)說(shuō)過(guò) Grunnt。一般都覺(jué)得他們都是打包工具,但其實(shí)還是有區(qū)別的 。更準(zhǔn)確的講,Grunt和Gulp屬于任務(wù)流工具Tast Runner , 而 webpack屬于模塊打包工具 Bundler。

打包工具的發(fā)展史

# Tast Runner

| Grunt

? Grunt的出現(xiàn)早于Gulp,Gulp是后起之秀。他們的本質(zhì)都是通過(guò) JavaScript 語(yǔ)法實(shí)現(xiàn)了shell script 命令的一些功能。比如利用jshint插件 實(shí)現(xiàn) JavaScript 代碼格式檢查這一個(gè)功能。早期需要手動(dòng)在命令行中輸入 jshint test.js,而 Grunt 則通過(guò)文件 Gruntfile.js 進(jìn)行配置

// Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({
    // js格式檢查任務(wù)
    jshint: {
      src: 'src/test.js'
    }
    //  代碼壓縮打包任務(wù)
    uglify: {}
  });
  // 導(dǎo)入任務(wù)插件
  grunt.loadnpmTasks('grunt-contrib-uglify');
  // 注冊(cè)自定義任務(wù), 如果有多個(gè)任務(wù)可以添加到數(shù)組中
  grunt.regusterTask('default', ['jshint'])
}

?

| Gulp

? Gulp吸取了Grunt的優(yōu)點(diǎn),擁有更簡(jiǎn)便的寫法,通過(guò)流(Stream)的概念來(lái)簡(jiǎn)化多任務(wù)之間的配置和輸出,讓任務(wù)更加簡(jiǎn)潔和容易上手。通過(guò)配置gulpfile.js文件來(lái)實(shí)現(xiàn),一個(gè)簡(jiǎn)單的gulpfile.js配置如下

// gulpfile.js
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');

// 代碼檢查任務(wù) gulp 采取了pipe 方法,用流的方法直接往下傳遞
gulp.task('lint', function() {
  return gulp.src('src/test.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

// 壓縮代碼任務(wù)
gulp.task('compress', function() {
  return gulp.src('src/test.js')
    .pipe(uglify())
    .pipe(gulp.dest('build'));
});

// 將代碼檢查和壓縮組合,新建一個(gè)任務(wù)
gulp.task('default', ['lint', 'compress']);

? 你會(huì)覺(jué)得,規(guī)則和結(jié)構(gòu)上都太像了。沒(méi)問(wèn)題,gulp本身就是借鑒了grunt的經(jīng)驗(yàn)進(jìn)行升級(jí)和加入一些新特性。正因?yàn)榱鞴芾矶嗳蝿?wù)配置輸出方式的提高,人們逐漸選擇使用Gulp而放棄grunt

# Bundler

| browserify

? browserify 是早期的模塊打包工具,是先驅(qū)者,踏實(shí)的瀏覽器端使用CommonJS規(guī)范(require--module.export)的格式組織代碼成為可能。在這之前,因?yàn)镃ommonJS與瀏覽器特性的不兼容問(wèn)題,更多使用的是AMD(defined--require)規(guī)范,當(dāng)然后來(lái)又發(fā)展了ES6模塊規(guī)范(require--export

? 假設(shè)有如下模塊add.js 和 文件test.js,test.js 使用CommonJS規(guī)范導(dǎo)入了模塊add.js

// add.js
module.exports = function(a, b) {
  return a + b
};

// test.js
var add = require('./add.js');
console.log(add(1, 2));  // 3

? 我們知道,如果直接執(zhí)行是執(zhí)行不成功的,因?yàn)闉g覽器無(wú)法識(shí)別CommonJS語(yǔ)法,而browserify就是用來(lái)處理這個(gè)問(wèn)題的,他將CommonJS語(yǔ)法進(jìn)行裝換,在命令行執(zhí)行功如下

browserify test.js > bundle.js

? 生成的bundle.js就是已經(jīng)處理完畢,可供瀏覽器執(zhí)行使用的文件,只需要將它插入到<script>中即可。

| webpack

? webpack是后起之秀,它支持了AMD 和 CommonJS 類型,通過(guò)loader 機(jī)制也可以使用ES6模塊格式。還有強(qiáng)大的 code splitting。webpack 是個(gè)十分強(qiáng)大的工具,它正在想一個(gè)全能型的構(gòu)建工具發(fā)展。

? webpack通過(guò)配置文件 webpack.config.js 進(jìn)行功能配置,一個(gè)配置案例如下

'use strict'
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const merge = require('webpack-merge')
const utils = require('./utils')

var config = {
  // 入口
  entry: {
    app: './src/main.js'
  },
  // 出口
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  // 加載器配置(需要加載器轉(zhuǎn)化的模塊類型)
  module: {
    rules: [
      {
        test: '/\.css$/',
        use: [ 'style-loader', 'css-loader' ]
      }
    ]
  }
  // 插件
  plugins: [
    new webpack.DefinePlugin({
      'process.env': require('../config/dev.env')
    }),
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
  ]

}

module.exports = config

? 一個(gè)相比比較全面的配置主要包含五個(gè)部分: 入口,出口,加載器,插件,模式。分別指定了開(kāi)始讀取文件的位置,編譯后輸出文件的路徑,ES6語(yǔ)法轉(zhuǎn)化加載器,更復(fù)雜功能的插件以及指定執(zhí)行的環(huán)境變量。
?

# 區(qū)別

? 相信大家看完上文后對(duì)于他們的區(qū)別也心中有數(shù)

? gulp和grunt是流管理工具,通過(guò)一個(gè)個(gè)task配置執(zhí)行用戶需要的功能,如格式檢驗(yàn),代碼壓縮等,值得一提的是,經(jīng)過(guò)這兩者處理的代碼只是局部變量名被替換簡(jiǎn)化,整體并沒(méi)有發(fā)生改變,還是你的代碼。

? 而webpack則進(jìn)行了更徹底的打包處理,更加偏向?qū)δK語(yǔ)法規(guī)則進(jìn)行轉(zhuǎn)換。主要任務(wù)是突破瀏覽器的鴻溝,將原本瀏覽器不能識(shí)別的規(guī)范和各種各樣的靜態(tài)文件進(jìn)行分析,壓縮,合并,打包,最后生成瀏覽器支持的代碼,因此,webapck打包過(guò)后的代碼已經(jīng)不是你寫的代碼了,或許你再去看,已經(jīng)看不懂啦

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 Webpack 1.1 概念簡(jiǎn)介 1.1.1 WebPack是什么 1、一個(gè)打包工具 2、一個(gè)模塊加載工具 3...
    Kevin_Junbaozi閱讀 7,017評(píng)論 0 16
  • 2.2 Grunt——js項(xiàng)目命令行構(gòu)建工具 Grunt是一個(gè)基于任務(wù)的JavaScript項(xiàng)目命令行構(gòu)建工具,...
    Kevin_Junbaozi閱讀 862評(píng)論 0 3
  • 在現(xiàn)在的前端開(kāi)發(fā)中,前后端分離、模塊化開(kāi)發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等等一些原本后端的思想開(kāi)始...
    Charlot閱讀 5,659評(píng)論 1 32
  • 對(duì)網(wǎng)站資源進(jìn)行優(yōu)化,并使用不同瀏覽器測(cè)試并不是網(wǎng)站設(shè)計(jì)過(guò)程中最有意思的部分,但是這個(gè)過(guò)程中的很多重復(fù)的任務(wù)能夠使用...
    懵逼js閱讀 1,162評(píng)論 0 8
  • 九曲清江飛柳絮,南雁游空,寂寞無(wú)人語(yǔ)。誰(shuí)在岸堤成碧樹(shù)。三秋流水東歸去。 夜里家書情欲訴,淚滿沾襟,父母安康否?昔日...
    沙瀑閱讀 440評(píng)論 38 56

友情鏈接更多精彩內(nèi)容