認識 webpack

為什麼我們需要 Webpack

Webpack 是什麼?

Webpack 就是一個前端的打包工具,將我們開發好的東西,打包成瀏覽器看得懂的格式。

像是現在有許多的前端工具,例如前端的三大框架(React、Vue、Angular)。那每一個前端框架都有自己的寫法,我們需要將這些不同的寫法,整合成瀏覽器看得懂的三個東西(HTML、CSS、JS)。

例如 React 裡有 JSX 的寫法,不同瀏覽器支援的不同 CSS 前綴。這時候就需要有一個工具幫我們轉換成瀏覽器看得懂的格式,統一這些打包的規則,這時候就需要 Webpack。

前端的框架都會有自己的 CLI,CLI 的好處會幫我們建立好前端專案,幫我們處理好 Webpack 的配置。但因為少做了這個部分,我們就容易會忽略掉他的配置原理,如果今天遇到打包(bundle)問題時,就會變得不知道如何解決,所以要好好的認識這個工具。

從 0 建立 Webpack 前端專案

  1. npm init ,就會出現 package.json,它就像是整個專案的藍圖,會記錄安裝了什麼套件。
  2. npm i webpack -D 為以下的縮寫,npm i webpack --save-dev
  3. 安裝好 Webpack 之後,建立 src 資料夾。更改 package.json 裡面的 script。
1
2
3
script:{
"build": "webpack"
}
  1. 更改完後,下 npm run build 指令,就會出現 dist 資料夾。因為還沒有寫 webpack.config.js,所以預設專案的路口為 src/index.js。
  2. 新增 webpack.config.js 檔案。

配置 webpack.config.js

Concepts | webpack

設定 webpack.config.js 的目的在於,當 webpack 在打包的時候,會根據裡面的內容配置進行打包。

左邊的欄位為不同的設定,分為以下五種。

  • Entry
    • 檔案入口查看 index.js
  • Output
    • 檔案的出口
  • Loaders
    • index.js 裡面可能會 import 其他的 js 或 css,Loader 就可以去辨識除了 js 以外的檔案,可以想成文件在閱讀相關的事情。
  • Plugins
    • 除了讀檔案以外的事情,例如讀檔案前要清空資料夾本身的內容,這件事情 Webpack 做不到,所以需要依靠插件。
  • Mode
    • 分為開發與上線模式,檔案也希望越小越好。

測試打包結果 DevServer

根據文件設定好 Entry 與 Output 之後,可以使用 webpack server 來測試打包後是否正常。

1
2
3
"script":{
"dev": "webpack serve"
}

在一開始起 server 的時候,要先在 dist 檔案裡加 index.html,將剛打包好的 index.js 引入。

DevServer | webpack

在 webpack.config.js 中設定啟動 DevServer 的根據資料夾,例如我們將打包好的東西放在 dist 資料夾,就可以設定為 dist。

1
2
3
4
5
6
7
8
9
10
const path = require('path');

module.exports = {
//...
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
},
};

設定 mode

Mode | webpack

以 production 的來講,他會把檔案中的空格都拿掉。不同 mode 會有不同的設定。

1
2
3
module.exports = {
mode: 'development',
};

Loader 和 Plugin 的運用

使用 Loader

當今天在 index.js 裡面引入 style.css,Webpack 預設只能引入 JavaScript,所以他會看不懂 CSS 時就會報錯,這時就需要使用 Loader。

css-loader | webpack

在 webpack.config.js 裡面加上 module。

1
2
3
4
5
6
7
8
9
10
module.exports = {
module: {
rules: [
{
test: /\.(css|scss)$/i,
use: ["style-loader", "css-loader"],
},
],
},
};

那 module 裡面可以放很多設定的 rule。

在做 bundle 的時候,我們會希望他的名字不一樣,因為會有快取的問題。所以要保證用戶是用最新的檔案,可以在 output 的時候加上[hash]

1
2
3
4
5
6
output: {
// 產生的檔案路徑
path: path.resolve(__dirname, 'dist'),
// 產生的檔案名
filename: 'main.[hash].bundle.js',
},

使用 Plugin

每次 index.html 裡面的 js 檔名字都會改變,所以就需要靠 plugin 去幫忙。

HtmlWebpackPlugin | webpack

讓 Webpack 直接幫我複製 html,還有插入 js 檔。

那麼根據我外面設定的 html template,根據那個檔案進行複製。

1
2
3
4
5
plugins: [
new HtmlWebpackPlugin({
template: './base.html'
}),
]

產生 css template 的插件。

MiniCssExtractPlugin | webpack

1
2
3
4
5
6
plugins: [
// 靠這一個插件可以將css自動引入
new MiniCssExtractPlugin({
filename: 'main.[hash].css'
})
],

什麼是 Babel

像是 React 中有一些 JS 比較先進的語法,這時候就需要 Babel 協助。

像是 class 有私有變數的寫法

1
2
3
4
5
6
class Test{
#a = 1
}

const tt = new Test
console.log('tt.a',tt.a);

Babel Setup

裡面有分成兩種寫法

  1. 寫在 webpack 裡
  2. 另外寫在 babel.config.json 裡

加上 sourceMap 可以讓我們更好的 debug。

1
devtool: 'source-map',

Asset Modules 介紹

Asset Modules | webpack

例如說 我們今天有一個 gif 檔,想要把他引入 css 檔案中,他可能就會報錯。

以下就是讓 webpack 看得懂 gif 檔案。

1
2
3
4
5
6
7
8
module: {
rules: [
{
test: /\.gif/,
type: 'asset/resource'
}
]
},

認識 webpack
https://phoebeho.com/Web/20220326/1469773149/
作者
Phoebe
發布於
2022年3月26日
許可協議