深入淺出Webpack 摘要 入門

模塊化

模塊化是指把一個(gè)復(fù)雜的系統(tǒng)分解到多個(gè)模塊以方便編碼。

缺點(diǎn)

  • 命名空間沖突,兩個(gè)庫可能會(huì)使用同一個(gè)名稱,例如 ZeptojQuery都被放在 window.$ 下;
  • 無法合理地管理項(xiàng)目的依賴和版本;
  • 無法方便地控制依賴的加載順序。
CommonJS

CommonJS 是一種使用廣泛的 JavaScript 模塊化規(guī)范,核心思想是通過 require 方法來同步地加載依賴的其他模塊,通過 module.exports 導(dǎo)出需要暴露的接口。

優(yōu)點(diǎn):代碼可復(fù)用于 Node.js 環(huán)境下并運(yùn)行,例如做同構(gòu)應(yīng)用;通過 NPM 發(fā)布的很多第三方模塊都采用了 CommonJS 規(guī)范。
缺點(diǎn):代碼無法直接運(yùn)行在瀏覽器環(huán)境下,必須通過工具轉(zhuǎn)換成標(biāo)準(zhǔn)的 ES5。

// 導(dǎo)入
const moduleA = require('./moduleA');

// 導(dǎo)出
module.exports = moduleA.someFunc;
ES6 模塊化

它在語言的層面上實(shí)現(xiàn)了模塊化。瀏覽器廠商和 Node.js 都宣布要原生支持該規(guī)范。它將逐漸取代 CommonJSAMD 規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。

// 導(dǎo)入
import { readFile } from 'fs';
import React from 'react';
// 導(dǎo)出
export function hello() {};
export default {
  // ...
};
樣式文件中的模塊化
// util.scss 文件

// 定義樣式片段
@mixin center {
  // 水平豎直居中
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
}

// main.scss 文件

// 導(dǎo)入和使用 util.scss 中定義的樣式片段
@import "util";
#box{
  @include center;
}

常見的構(gòu)建工具及對(duì)比

各種可以提高開發(fā)效率的新思想和框架被發(fā)明。但是這些東西都有一個(gè)共同點(diǎn):源代碼無法直接運(yùn)行,必須通過轉(zhuǎn)換后才可以正常運(yùn)行。

構(gòu)建就是做這件事情,把源代碼轉(zhuǎn)換成發(fā)布到線上的可執(zhí)行 JavaScrip、CSSHTML 代碼,包括如下內(nèi)容。

  • 代碼轉(zhuǎn)換:TypeScript 編譯成 JavaScript、SCSS 編譯成 CSS 等。
  • 文件優(yōu)化:壓縮 JavaScriptCSS、HTML代碼,壓縮合并圖片等。
  • 代碼分割:提取多個(gè)頁面的公共代碼、提取首屏不需要執(zhí)行部分的代碼讓其異步加載。
  • 模塊合并:在采用模塊化的項(xiàng)目里會(huì)有很多個(gè)模塊和文件,需要構(gòu)建功能把模塊分類合并成一個(gè)文件。
  • 自動(dòng)刷新:監(jiān)聽本地源代碼的變化,自動(dòng)重新構(gòu)建、刷新瀏覽器。
  • 代碼校驗(yàn):在代碼被提交到倉(cāng)庫前需要校驗(yàn)代碼是否符合規(guī)范,以及單元測(cè)試是否通過。
  • 自動(dòng)發(fā)布:更新完代碼后,自動(dòng)構(gòu)建出線上發(fā)布代碼并傳輸給發(fā)布系統(tǒng)。

構(gòu)建其實(shí)是工程化、自動(dòng)化思想在前端開發(fā)中的體現(xiàn),把一系列流程用代碼去實(shí)現(xiàn),讓代碼自動(dòng)化地執(zhí)行這一系列復(fù)雜的流程。 構(gòu)建給前端開發(fā)注入了更大的活力,解放了我們的生產(chǎn)力

Npm Script

Npm Script 是一個(gè)任務(wù)執(zhí)行者。Npm 是在安裝 Node.js 時(shí)附帶的包管理器,Npm Script則是 Npm 內(nèi)置的一個(gè)功能,允許在 package.json文件里面使用 scripts 字段定義任務(wù):

{
  "scripts": {
    "dev": "node dev.js",
    "pub": "node build.js"
  }
}
// 每個(gè)屬性對(duì)應(yīng)一段 Shell 腳本其底層實(shí)現(xiàn)原理是通過調(diào)用 Shell 去運(yùn)行腳本命令 
// 例如執(zhí)行 npm run pub 命令等同于執(zhí)行命令 node build.js。
Grunt

GruntNpm Script 類似,也是一個(gè)任務(wù)執(zhí)行者。Grunt 有大量現(xiàn)成的插件封裝了常見的任務(wù),也能管理任務(wù)之間的依賴關(guān)系,自動(dòng)化執(zhí)行依賴的任務(wù),每個(gè)任務(wù)的具體執(zhí)行代碼和依賴關(guān)系寫在配置文件 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當(dāng)我們?cè)诮K端中啟動(dòng) grunt 時(shí)需要執(zhí)行哪些任務(wù)
  grunt.registerTask('dev', ['uglify','watch']);
};
// 在項(xiàng)目根目錄下執(zhí)行命令 grunt dev 就會(huì)啟動(dòng) JavaScript 文件壓縮和自動(dòng)刷新功能。

優(yōu)點(diǎn):靈活,它只負(fù)責(zé)執(zhí)行你定義的任務(wù);大量的可復(fù)用插件封裝好了常見的構(gòu)建任務(wù)。
缺點(diǎn):集成度不高,要寫很多配置后才可以用,無法做到開箱即用。

Gulp

Gulp 是一個(gè)基于流的自動(dòng)化構(gòu)建工具。 除了可以管理和執(zhí)行任務(wù),還支持監(jiān)聽文件、讀寫文件。Gulp被設(shè)計(jì)得非常簡(jiǎn)單,只通過下面5個(gè)方法就可以勝任幾乎所有構(gòu)建場(chǎng)景:

  • 通過 gulp.task 注冊(cè)一個(gè)任務(wù);
  • 通過 gulp.run 執(zhí)行任務(wù);
  • 通過 gulp.watch 監(jiān)聽文件變化;
  • 通過 gulp.src 讀取文件;
  • 通過 gulp.dest 寫文件。
// 引入 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 任務(wù)
gulp.task('sass', function() {
  // 讀取文件通過管道喂給插件
  gulp.src('./scss/*.scss')
    // SCSS 插件把 scss 文件編譯成 CSS 文件
    .pipe(sass())
    // 輸出文件
    .pipe(gulp.dest('./css'));
});

// 合并壓縮 JS
gulp.task('scripts', function() {
  gulp.src('./js/*.js')
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dist'));
});

// 監(jiān)聽文件變化
gulp.task('watch', function(){
  // 當(dāng) scss 文件被編輯時(shí)執(zhí)行 SCSS 任務(wù)
  gulp.watch('./scss/*.scss', ['sass']);
  gulp.watch('./js/*.js', ['scripts']);    
});

優(yōu)點(diǎn):好用又不失靈活,既可以單獨(dú)完成構(gòu)建也可以和其它工具搭配使用。相對(duì)于GruntGulp增加了監(jiān)聽文件、讀寫文件、流式處理的功能。
缺點(diǎn):集成度不高,要寫很多配置后才可以用,無法做到開箱即用。

webpack

Webpack是一個(gè)打包模塊化 JavaScript的工具,在 Webpack 里一切文件皆模塊,通過 Loader 轉(zhuǎn)換文件,通過 Plugin 注入鉤子,最后輸出由多個(gè)模塊組合成的文件。Webpack 專注于構(gòu)建模塊化項(xiàng)目。

優(yōu)點(diǎn):專注于處理模塊化的項(xiàng)目,能做到開箱即用一步到位;通過 Plugin 擴(kuò)展,完整好用又不失靈活;使用場(chǎng)景不僅限于Web 開發(fā);社區(qū)龐大活躍,經(jīng)常引入緊跟時(shí)代發(fā)展的新特性,能為大多數(shù)場(chǎng)景找到已有的開源擴(kuò)展;良好的開發(fā)體驗(yàn)。
缺點(diǎn):只能用于采用模塊化開發(fā)的項(xiàng)目

Rollup

Rollup 是一個(gè)和 Webpack 很類似但專注于 ES6的模塊打包工具。 Rollup 的亮點(diǎn)在于能針對(duì) ES6 源碼進(jìn)行 Tree Shaking 以去除那些已被定義但沒被使用的代碼,以及 Scope Hoisting 以減小輸出文件大小提升運(yùn)行性能。 然而 Rollup 的這些亮點(diǎn)隨后就被 Webpack 模仿和實(shí)現(xiàn)。Rollup 在用于打包 JavaScript 庫時(shí)比 Webpack 更加有優(yōu)勢(shì),因?yàn)槠浯虬鰜淼拇a更小更快。 但功能不夠完善,很多場(chǎng)景都找不到現(xiàn)成的解決方案。

  • Rollup 是在 Webpack 流行后出現(xiàn)的替代品;
  • Rollup 生態(tài)鏈還不完善,體驗(yàn)不如 Webpack;
  • Rollup 功能不如 Webpack完善,但其配置和使用更加簡(jiǎn)單;
  • Rollup 不支持 Code Spliting,但好處是打包出來的代碼中沒有 Webpack 那段模塊的加載、執(zhí)行和緩存的代碼

安裝與使用

# 安裝最新穩(wěn)定版 -D 安裝到開發(fā)依賴
npm i -D webpack

安裝完后你可以通過這些途徑運(yùn)行安裝到本項(xiàng)目的 Webpack

  • 在項(xiàng)目根目錄下對(duì)應(yīng)的命令行里通過輸入 node_modules/.bin/webpack運(yùn)行
  • Npm Script 里定義的任務(wù)會(huì)優(yōu)先使用本項(xiàng)目下的 Webpack,代碼如下:
"scripts": {
    "start": "webpack --config webpack.config.js"
}

Webpack 在執(zhí)行構(gòu)建時(shí)默認(rèn)會(huì)從項(xiàng)目根目錄下的webpack.config.js 文件讀取配置。

const path = require('path');

// 通過 CommonJS 規(guī)范導(dǎo)出一個(gè)描述如何構(gòu)建的 Object 對(duì)象。 

module.exports = {
  // JavaScript 執(zhí)行入口文件
  entry: './main.js',
  output: {
    // 把所有依賴的模塊合并輸出到一個(gè) bundle.js 文件
    filename: 'bundle.js',
    // 輸出文件都放到 dist 目錄下
    path: path.resolve(__dirname, './dist'),
  }
};

執(zhí)行 webpack 命令運(yùn)行 Webpack 構(gòu)建,你會(huì)發(fā)現(xiàn)目錄下多出一個(gè) dist 目錄,里面有個(gè) bundle.js 文件, bundle.js文件是一個(gè)可執(zhí)行的 JavaScript文件,它包含頁面所依賴的模塊及內(nèi)置的 webpackBootstrap 啟動(dòng)函數(shù)。 這時(shí)你用瀏覽器打開 index.html網(wǎng)頁將會(huì)看到正常的展示。

Webpack 是一個(gè)打包模塊化 JavaScript 的工具,它會(huì)從 main.js 出發(fā),識(shí)別出源碼中的模塊化導(dǎo)入語句, 遞歸的尋找出入口文件的所有依賴,把入口和其所有依賴打包到一個(gè)單獨(dú)的文件中。

使用Loader

Webpack 不原生支持解析 如CSS 等文件。要支持非 JavaScript類型的文件,需要使用 WebpackLoader 機(jī)制。

const path = require('path');

module.exports = {
 // JavaScript 執(zhí)行入口文件
 entry: './main.js',
 output: {
   // 把所有依賴的模塊合并輸出到一個(gè) bundle.js 文件
   filename: 'bundle.js',
   // 輸出文件都放到 dist 目錄下
   path: path.resolve(__dirname, './dist'),
 },
 module: {
   rules: [
     {
       // 用正則去匹配要用該 loader 轉(zhuǎn)換的 CSS 文件
       test: /\.css$/,
       use: ['style-loader', 'css-loader?minimize'],
     },
     // 或者
     {
       test: /\.css$/,
       use: [
         'style-loader',
         {
           loader:'css-loader',
           options: {
             minimize: true,
           }
         }
       ],
     }
   ]
 }
};

Loader 可以看作具有文件轉(zhuǎn)換功能的翻譯員,配置里的 module.rules 數(shù)組配置了一組規(guī)則,告訴 Webpack 在遇到哪些文件時(shí)使用哪些 Loader 去加載和轉(zhuǎn)換。 如上配置告訴 Webpack 在遇到以 .css結(jié)尾的文件時(shí)先使用 css-loader 讀取 CSS 文件,再交給 style-loader 把 CSS 內(nèi)容注入到 JavaScript 里。 在配置 Loader 時(shí)需要注意的是:

  • use 屬性的值需要是一個(gè)由Loader 名稱組成的數(shù)組,Loader 的執(zhí)行順序是由后到前的;
  • 每一個(gè) Loader 都可以通過 URL querystring 的方式傳入?yún)?shù),例如 css-loader?minimize 中的 minimize 告訴 css-loader 要開啟 CSS 壓縮。

在重新執(zhí)行 Webpack 構(gòu)建前要先安裝新引入的 Loader

npm i -D style-loader css-loader

安裝成功后重新執(zhí)行構(gòu)建時(shí),你會(huì)發(fā)現(xiàn) bundle.js 文件被更新了,里面注入了在 main.css 中寫的 CSS,而不是會(huì)額外生成一個(gè) CSS 文件。 但是重新刷新 index.html 網(wǎng)頁時(shí)將會(huì)發(fā)現(xiàn)樣式生效了!這其實(shí)都是 style-loader 的功勞,它的工作原理大概是把 CSS 內(nèi)容用 JavaScript 里的字符串存儲(chǔ)起來, 在網(wǎng)頁執(zhí)行 JavaScript 時(shí)通過 DOM 操作動(dòng)態(tài)地往 HTML head標(biāo)簽里插入 HTML style標(biāo)簽。 也許你認(rèn)為這樣做會(huì)導(dǎo)致 JavaScript 文件變大并導(dǎo)致加載網(wǎng)頁時(shí)間變長(zhǎng),想讓 Webpack 單獨(dú)輸出 CSS 文件。可使用 Webpack Plugin 機(jī)制來實(shí)現(xiàn)。

還可以在源碼中指定用什么 Loader 去處理文件。 以加載 CSS 文件為例,在 main.js 加上以下代碼即可。

require('style-loader!css-loader?minimize!./main.css');
// 指定對(duì) ./main.css 這個(gè)文件先采用 css-loader 再采用 style-loader 轉(zhuǎn)換。

使用Plugin

Plugin 是用來擴(kuò)展 Webpack 功能的,通過在構(gòu)建流程里注入鉤子實(shí)現(xiàn),它給 Webpack 帶來了很大的靈活性。

下例展示通過 Plugin 把注入到 bundle.js 文件里的 CSS 提取到單獨(dú)的文件中。

安裝插件:npm i -D extract-text-webpack-plugin

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  // JavaScript 執(zhí)行入口文件
  entry: './main.js',
  output: {
    // 把所有依賴的模塊合并輸出到一個(gè) bundle.js 文件
    filename: 'bundle.js',
    // 把輸出文件都放到 dist 目錄下
    path: path.resolve(__dirname, './dist'),
  },
  module: {
    rules: [
      {
        // 用正則去匹配要用該 loader 轉(zhuǎn)換的 CSS 文件
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          // 轉(zhuǎn)換 .css 文件需要使用的 Loader
          use: ['css-loader'],
        }),
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin({
      // 從 .js 文件中提取出來的 .css 文件的名稱
      filename: `[name]_[contenthash:8].css`,
    }),
  ]
};

重新構(gòu)建,你會(huì)發(fā)現(xiàn) dist 目錄下多出一個(gè) main_1a87a56a.css 文件,bundle.js 里也沒有 CSS 代碼了,再把該 CSS 文件引入到 index.html 里就完成了。

從以上代碼可以看出, Webpack 是通過 plugins 屬性來配置需要使用的插件列表的。 plugins 屬性是一個(gè)數(shù)組,里面的每一項(xiàng)都是插件的一個(gè)實(shí)例,在實(shí)例化一個(gè)組件時(shí)可以通過構(gòu)造函數(shù)傳入這個(gè)組件支持的配置屬性。

例如 ExtractTextPlugin 插件的作用是提取出 JavaScript 代碼里的 CSS 到一個(gè)單獨(dú)的文件。 對(duì)此你可以通過插件的 filename屬性,告訴插件輸出的 CSS 文件名稱是通過 [name]_[contenthash:8].css字符串模版生成的,里面的 [name] 代表文件名稱, [contenthash:8] 代表根據(jù)文件內(nèi)容算出的8位 hash 值。

使用 DevServer

前面只是讓 Webpack 正常運(yùn)行起來了,但在實(shí)際開發(fā)中你可能會(huì)需要:

  • 提供 HTTP 服務(wù)而不是使用本地文件預(yù)覽;
  • 監(jiān)聽文件的變化并自動(dòng)刷新網(wǎng)頁,做到實(shí)時(shí)預(yù)覽;
  • 支持 Source Map,以方便調(diào)試。

Webpack 原生支持上述第2、3點(diǎn)內(nèi)容,再結(jié)合官方提供的開發(fā)工具 DevServer 也可以很方便地做到第1點(diǎn)。DevServer會(huì)啟動(dòng)一個(gè) HTTP 服務(wù)器用于服務(wù)網(wǎng)頁請(qǐng)求,同時(shí)會(huì)幫助啟動(dòng)Webpack ,并接收 Webpack 發(fā)出的文件更變信號(hào),通過 WebSocket 協(xié)議自動(dòng)刷新網(wǎng)頁做到實(shí)時(shí)預(yù)覽。

安裝:npm i -D webpack-dev-server

安裝成功后執(zhí)行 webpack-dev-server 命令, DevServer 就啟動(dòng)了。

DevServer 啟動(dòng)的 HTTP 服務(wù)器監(jiān)聽在 http://localhost:8080/(端口可以設(shè)置),DevServer 啟動(dòng)后會(huì)一直駐留在后臺(tái)保持運(yùn)行,訪問這個(gè)網(wǎng)址你就能獲取項(xiàng)目根目錄下的 index.html。 用瀏覽器打開這個(gè)地址你會(huì)發(fā)現(xiàn)頁面空白錯(cuò)誤原因是 ./dist/bundle.js 加載404了。 同時(shí)你會(huì)發(fā)現(xiàn)并沒有文件輸出到 dist 目錄,原因是 DevServer 會(huì)把 Webpack 構(gòu)建出的文件保存在內(nèi)存中,在要訪問輸出的文件時(shí),必須通過HTTP服務(wù)訪問。 由于 DevServer 不會(huì)理會(huì) webpack.config.js 里配置的 output.path 屬性,所以要獲取 bundle.js 的正確 URLhttp://localhost:8080/bundle.js

所以在 index.html 中這樣引入 <script src="bundle.js"></script> 而不是引入預(yù)料中打包后的dist文件下的bundle.js

實(shí)時(shí)預(yù)覽

Webpack 在啟動(dòng)時(shí)可以開啟監(jiān)聽模式,開啟監(jiān)聽模式后 Webpack 會(huì)監(jiān)聽本地文件系統(tǒng)的變化,發(fā)生變化時(shí)重新構(gòu)建出新的結(jié)果。Webpack 默認(rèn)是關(guān)閉監(jiān)聽模式的,你可以在啟動(dòng) Webpack 時(shí)通過 webpack --watch 來開啟監(jiān)聽模式。

通過 DevServer 啟動(dòng)的 Webpack 會(huì)開啟監(jiān)聽模式,當(dāng)發(fā)生變化時(shí)重新執(zhí)行完構(gòu)建后通知 DevServer。 DevServer會(huì)Webpack在構(gòu)建出的 JavaScript 代碼里注入一個(gè)代理客戶端用于控制網(wǎng)頁,網(wǎng)頁和 DevServer 之間通過 WebSocket 協(xié)議通信, 以方便 DevServer主動(dòng)向客戶端發(fā)送命令。 DevServer 在收到來自 Webpack文件變化通知時(shí)通過注入的客戶端控制網(wǎng)頁刷新。

如果嘗試修改 index.html 文件并保存,你會(huì)發(fā)現(xiàn)這并不會(huì)觸發(fā)以上機(jī)制,導(dǎo)致這個(gè)問題的原因是 Webpack 在啟動(dòng)時(shí)會(huì)以配置里的 entry 為入口去遞歸解析出 entry 所依賴的文件,只有 entry 本身和依賴的文件才會(huì)被 Webpack 添加到監(jiān)聽列表里。 而 index.html 文件是脫離了JavaScript 模塊化系統(tǒng)的,所以 Webpack 不知道它的存在。

模塊熱替換

除了通過重新刷新整個(gè)網(wǎng)頁來實(shí)現(xiàn)實(shí)時(shí)預(yù)覽,DevServer 還有一種被稱作模塊熱替換的刷新技術(shù)。 模塊熱替換能做到在不重新加載整個(gè)網(wǎng)頁的情況下,通過將被更新過的模塊替換老的模塊,再重新執(zhí)行一次來實(shí)現(xiàn)實(shí)時(shí)預(yù)覽。 模塊熱替換相對(duì)于默認(rèn)的刷新機(jī)制能提供更快的響應(yīng)和更好的開發(fā)體驗(yàn)。 模塊熱替換默認(rèn)是關(guān)閉的,要開啟模塊熱替換,你只需在啟動(dòng) DevServer 時(shí)帶上 --hot參數(shù)。

支持 Source Map

在瀏覽器中運(yùn)行的 JavaScript 代碼都是編譯器輸出的代碼,你可能需要通過斷點(diǎn)調(diào)試去找出問題。 在編譯器輸出的代碼上進(jìn)行斷點(diǎn)調(diào)試是一件辛苦和不優(yōu)雅的事情, 調(diào)試工具可以通過 Source Map 映射代碼,讓你在源代碼上斷點(diǎn)調(diào)試。 Webpack 支持生成 Source Map,只需在啟動(dòng)時(shí)帶上 --devtool source-map 參數(shù)。

核心概念

  • Entry:入口,Webpack 執(zhí)行構(gòu)建的第一步將從 Entry 開始,可抽象成輸入。
  • Module:模塊,在 Webpack 里一切皆模塊,一個(gè)模塊對(duì)應(yīng)著一個(gè)文件。Webpack 會(huì)從配置的 Entry開始遞歸找出所有依賴的模塊。
  • Chunk:代碼塊,一個(gè) Chunk 由多個(gè)模塊組合而成,用于代碼合并與分割。
  • Loader:模塊轉(zhuǎn)換器,用于把模塊原內(nèi)容按照需求轉(zhuǎn)換成新內(nèi)容。
  • Plugin:擴(kuò)展插件,在 Webpack 構(gòu)建流程中的特定時(shí)機(jī)注入擴(kuò)展邏輯來改變構(gòu)建結(jié)果或做你想要的事情。
  • Output:輸出結(jié)果,在 Webpack 經(jīng)過一系列處理并得出最終想要的代碼后輸出結(jié)果。

Webpack 啟動(dòng)后會(huì)從 Entry 里配置的 Module 開始遞歸解析 Entry 依賴的所有 Module。 每找到一個(gè) Module, 就會(huì)根據(jù)配置的 Loader 去找出對(duì)應(yīng)的轉(zhuǎn)換規(guī)則,對(duì) Module 進(jìn)行轉(zhuǎn)換后,再解析出當(dāng)前 Module 依賴的 Module。 這些模塊會(huì)以 Entry 為單位進(jìn)行分組,一個(gè) Entry 和其所有依賴的 Module 被分到一個(gè)組也就是一個(gè) Chunk。最后 Webpack 會(huì)把所有 Chunk 轉(zhuǎn)換成文件輸出。 在整個(gè)流程中 Webpack 會(huì)在恰當(dāng)?shù)臅r(shí)機(jī)執(zhí)行 Plugin 里定義的邏輯。

最后編輯于
?著作權(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ù)。

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