avatar

目錄
webpack 介紹

webpack

webpack 在處理整個專案時,它會在內部建立一個依賴的關係圖,
裡面記錄著每個頁面所需要用到的模組,並將每個模組綑綁成一個或多個來使用。簡單來說就是可以幫我們打包所有用到的 JavaScript 、SASS … 等檔案,編譯後讓瀏覽器可讀取。另一個工具 gulp 跟 webpack 的差異在一個是協助自動化,另外一個是協助前端打包的。
gulp 比較偏向命令式的編寫設定,也就是說所有的編譯動作的邏輯都要自己編寫,webpack 就偏向設定。

安裝

首先需要用 npm 安裝 webpack 與 webpack-dev-server, 如果你第一次裝,可以用 -g 安裝,以便在任何地方都可以使用該指令:

webpack //打包工具
webpack-dev-server //即時產生一個 server 看執行結果

npm install -g webpack webpack-dev-server

接著安裝指令包

npm install webpack-cli -g

專案使用

1.建立專案資料夾

2.建立 NPM (參照 NPM 文件,記得移動到專案資料夾的目錄)

npm init

按照資訊設定,產生 package.json 內容會像以下

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "my-project",
"version": "1.0.0",
"description": "this is my project",
"main": "app.js",
"repository": {
"type": "git"
"url": "http://github.com/npm/npm.git"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

若想快速設定可用 npm init -y。設定結束後,會產生 package.json(設定紀錄檔)。

scripts 屬性可以自訂指令名稱及執行指令,設定完後,輸入
npm run 指令名稱 就可以執行了。

建議可在 package.json 加入以下 webpack-dev-server scripts

Code
1
2
3
"scripts": {
"dev": "webpack-dev-server --devtool eval --progress --colors --content-base build"
},

–devtool eval: 將把 source 加到我的 code
–progress 與 –colors: 反應現今程序執行狀況
–content-base build: 將 build 裡的 index.html 作為啟始頁

安裝 webpack 套件在專案資料夾裡:
npm install webpack webpack-cli --save-dev

3.用 NPM 安裝要使用的套件。安裝後的套件資訊,也會記錄在package.json 內。

紀錄的訊息會像是:

開發的時候會用到的套件

Code
1
2
3
4
5
"devDependencies": {
"webpack": "^4.18.0"
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
},

上線發佈後依然需要用到的套件

Code
1
2
3
4
5
"dependencies": {
"axios": "^0.19.0",
"bootstrap": "^4.3.1",
"jquery": "^3.4.1",
},

package.json 可以手動加入也可自動加入。
要自動加入的指令是 --save-dev ,在套件安裝時加上。

e.g.
npm install webpack webpack-cli --save-dev

4.建立 webpack.config.js 檔案,用來當作 webpack 的設定檔,檔名也不能亂取。

檔案內容:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
const path = require('path');
module.exports = {
//webpack打包的路徑及對象, index.js
entry: {
index: './index.js'
},
output: {
//這裡是打包後的檔案名稱
filename: 'bundle.js',
//打包後的路徑,這裡使用 path 模組的 resolve() 取得絕對位置,也就是目前專案的根目錄
path: path.resolve('./'),
}
};

使用 loader

告訴 webpack,該如何處理匯入的檔案(編譯打包),通常是 Javascript 但 webpack 不限於處理 Javascript,其他像是 Sass,圖片等也可處理,只要提供可處理的 loader。loader 的設定會寫在 module 的 rules 中。

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
//如果有一個以上的檔案需要打包,可以傳陣列給entry
entry: ['./index.js', './app.jsx'],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './'),
},
//將loader的設定寫在module的rules屬性中
module: {
//rules的值是一個陣列可以存放多個loader物件
rules: [
{ test: /.jsx$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react'] } } }
]
}
};

loader 物件屬性

test:指定編譯檔案的副檔名為何,用正規表達式來尋找結尾處為.jsx的檔案。

exclude:指定不編譯的路徑。

use:指定用來編譯符合副檔名條件的loader,這個物件裡面還有兩個屬性:

loader:指定進行編譯的套件
option:指定 loader 套件中的 presets 是什麼

其他 loader 對應:

CSS

CSS:style-loader、css-loader
SASS:sass-loader、node-sass

安裝:
npm install --save-dev autoprefixer css-loader node-sass postcss-loader precss sass-loader style-loader

設定

Code
1
2
3
4
5
6
7
8
9
10
// webpack.config.js

module: {
rules: [
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
}

使用

Code
1
2
// ./src/index.js
import './styles/style.scss'

PIC

file-loader、url-loader

npm install --save-dev url-loader

設定

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// webpack.config.js

module:{
rules:[
// url loader (for image)
{
test: /\.(jpe?g|png|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 40000 /* 小於 40kB 的圖片轉成 base64 */
}
}
]
}
],
[
// file-loader
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
}

使用

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ./src/image-viewer.js
import midImgUrl from './../assets/mid.jpeg'
import minImgUrl from './../assets/min.jpeg'

// midImg 會是被壓縮過的檔案名稱
const midImg = document.createElement('img')
midImg.src = midImgUrl
document.body.appendChild(midImg)

// minImg 是被注入在 bundle.js 中,可以直接使用
const minImg = document.createElement('img')
minImg.src = minImgUrl
document.body.appendChild(minImg)

export {midImg, minImg}

ES6 轉譯 ES5

babel-loader、babel-core、babel-preset-env

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader

設定

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// webpack.config.js

module: {
rules: [
// babel-loader
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'entry',
// targets: "> 0.25%, not dead"
targets: {
chrome: '69'
}
}
]
] // End of presets
} // End of options
}
} // End of Babel
];
}

開啟本機伺服器

在 webpack.config.js 中增加 devserver 的一些設定,例如要開啟的 port,如果沒有特別設定的話,port 的預設值為 8080,以下為了區隔所以設定 9000

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const path = require('path');
module.exports = {
entry: ['./index.js', './app.jsx'],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './'),
},
//將loader的設定寫在module的rules屬性中
module: {
//rules的值是一個陣列可以存放多個loader物件
rules: [
{ test: /.jsx$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'] } } },
{ test: /.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } }
]
},
//增加一個給devserver的設定
devServer: {
//指定開啟port為9000
port: 9000
}
};

Plugin

透過 clean-webpack-plugin 可以每次打包前都清除特定資料夾。

安裝

$ npm install clean-webpack-plugin --save-dev

Code
1
2
3
4
5
6
7
8
9
10
11
12
// webpack.config.js

const path = require('path')
const CleanWebpackPlugin = require('clean-webpack-plugin')

module.exports = {
// ...
plugins: [
new CleanWebpackPlugin(['dist']),
// ...
]
}

指令(命令提示字元下 or 終端機輸入)

看版本

webpack -v

打包

webpack -p

or

npm run start

開啟本機伺服器

webpack-dev-server

執行完後,打開瀏覽器輸入 http://localhost:9000 ,關閉 webpack-dev-server 開啟的 port,在命令提示字元的畫面上輸入 Ctrl+C。

參考:
https://webpack.js.org/concepts/#entry
https://ithelp.ithome.com.tw/articles/10200329
https://ithelp.ithome.com.tw/articles/10200459?sc=pt
Webpack 學習筆記(Webpack Note)