[Webpack] 前端打包工具(3)-概念

Ally Zeng
[AZ] 下筆記。
Published in
7 min readDec 17, 2019

F2E / Module bundler / Concepts

圖片來源: https://webpack.js.org/

雖然 Webpack 4 無須配置即可使用,但開發專案時難免會使用到預處理器 (Preprocessor)或是框架 (Frameworks)等等,為了因應不同需求,還是建議要了解 Webpack 的設定檔以便我們做一些更複雜的配置。

概念

一個基本的 Webpack 設定檔內容,主要由 entryoutputloaderplugins四大核心所組成。

webpack.config.js

module.exports = {
mode: 'production'
entry: './src/index.js',
output: {
filename: './dist/bundle.js',
},
module: {
rules: [ loaders,…]
},
plugins: […]
}

因此,在開始配置之前,我們要先理解 Webpack 的核心概念…。
或許你心裡已經開始 O.S.:怎麼還沒開始使用 Webpack ! …沒辦法,任何學習都得從打地基開始(攤手)。

入口 entry

專案的進入點 (entry points),預設為 ./src,可指定單一或多個進入點。
Webpack 會編譯與entry檔案相關聯的模組和函式庫。

# 單一進入點:用於函式庫(library)或一頁式網站

module.exports = {
// 完整寫法
entry: {
main: './src/index.js'
}
// 簡寫
entry: './src/index.js'
};

# 多個進入點: 需要將第三方資源(vendor)分開打包

module.exports = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
};

# 多頁面應用

module.exports = {
entry: {
pageOne : './src/pageOne/index.js',
pageTwo : './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js',
}
};

▎輸出 output

輸出 (output),預設為 ./disc,打包輸出的目錄及 bundles 檔案。
※ 雖然可指定單一/多個進入點,但輸出配置只能指定一個。

# 單一進入點

module.exports = {
entry: './src/index.js',
output: {
path: './dist',
filename: 'bundle.js'
}
// or
output: {
filename: './dist/bundle.js'
}
};

# 多個進入點(或代碼拆分(code splitting)、創建多個 bundle)

module.exports = {
entry: {
pageOne : './src/pageOne/index.js',
pageTwo : './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js',
}
output: {
path: './dist',
filename: '[name].bundle.js'
}
// or
output: {
filename: './dist/[name].bundle.js'
}
};

[name] : 使用入口名稱,該範例中會輸出 pageOne.bundle.js, pageTwo.bundle.js 以此類推。

loader

loader 主要是讓 Webpack 能夠處理非 JavaScript 檔案(Webpack 本身只理解 JavaScript),若需要編譯不同類型的檔案,如 html/css/js 預處理器、圖片、影片、字體等,就需要載入相對應的模組。

※ 例:讓 Webpack 載入 CSS 或將 TypeScript 轉為 JavaScript。
首先,安裝對應的 loader (通常命名為 xxx-loader)。

npm install --save-dev css-loader
npm install --save-dev ts-loader

將 loader 寫入 Webpack 設定檔的模組規則 module.rules 裡。

module.exports = {
module: {
rules: [
// loader array here...
{test: /\.css$/, use: 'css-loader'},
{test: /\.ts$/, use: 'ts-loader'}
]
}
};

屬性
test:需要轉換的檔案類型。
use: 要使用的 loader。

👉 更多 loaders

▎外掛 plugins

處理 loader 無法完成的各種任務。如打包優化、壓縮、熱更新( HMR)等等。

# webpack 內建 plugins (Built-in plugins)
需要安裝過 Webpack 才能使用內建 plugins:

npm install --save-dev webpack

然後在 Webpack 設定檔中使用 require() 載入 plugins,將需要的外掛寫入 plugins[] 屬性中:

// 使用內建 plugins
const webpack = require("webpack");
module.exports = {
plugins: [
// 定義環境變數
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"',
})
]
};

👉 更多 plugins

# 加入第三方 plugins ( Third party plugins)
先透過 npm 安裝第三方 plugins,以 html-webpack-plugin為例:

npm i html-webpack-plugin --save-dev

一樣在 Webpack 設定檔 require()進來,並寫入plugins[]中:

// 使用內建 plugins
const webpack = require("webpack");
// 使用第三方 plugins
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
// 打包生成一個 HTML5 檔
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 定義環境變數
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"',
})
]
};

👉 更多 第三方 plugins

▎模式 mode

Webpack 提供mode配置選項,可指定開發/生產環境,並啟用相應的功能。
development:不壓縮代碼,啟用開發工具(source-map、HMR...)。
production:會壓縮代碼,啟用打包優化。

在設定檔中配置:

module.exports = {
mode: "production" | "development" | "none"
};

或使用 Webpack CLI 指令:

// package.json
{
"scripts": {
"dev" : "webpack-dev-server --hot --open --mode development",
"build": "webpack --mode production",
}
}

--

--