Hello Webpack! Plugins 和瀏覽器快取

Hello Webpack! Plugins 和瀏覽器快取

plugin(插件)是替webpack擴充功能的函式庫。

瀏覽器快取 browser caching

每當瀏覽器打開一個網頁時, 它會將網頁的資源都下載下來, 這些資源包含js和css等等, 有些網站會需要大量的js, 就會讓網站的載入速度變慢, 在手機端時可能會更糟。

為了解決這個問題,快取(cache)就誕生了, 當同個頁面重新載入時, 若是有些資源並沒有變動, 那就把它存在某個地方, 下次又打開同個網頁時就可以直接取用不需要下載

那瀏覽器怎麼知道什麼時候要更新快取裡面的檔案呢? 如果無法更新的話, 那使用者不就永遠都無法看到最新的版本嗎?

瀏覽器是以檔名來識別一個檔案的, 因此一個解決辦法是: 當檔案內容有更動時, 就換一個名字, 這樣一來瀏覽器就會認為是新的檔案然後下載到新的版本

webpack可以幫我們做到這件事

webpack.config.js

1
2
3
4
5
6
7
output: {
// 完成打包之後產生的檔案名稱
// 使用contenthash模式, 每次檔案異動build完後, webpack幫我們產出一個新的亂碼名稱幫助更新快取
filename: "bundle.[contenthash].js",
path: path.resolve(__dirname, './dist'),
publicPath: 'dist/',
},

webpack在這邊採用一種叫md5的方式, 根據檔案內容加密, 一旦檔案有更動, 就會產生新的

這個方法也適用於css, 只要更改minicssextractplugin中的filename, 就可以設定新css檔案的命名模式

Clean Plugin for Webpack

由於每次build都會產生新的檔案, 就得並不會消失,dist資料夾會變得很臃腫, 要怎麼解決呢?

可以使用一款叫clean webpack plugin的插件解決這個問題

webpack.config.js

1
2
3
4
5
6
7
8
9
// 開頭引入
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// 加到plugins區塊
// plugin 陣列
plugins: [
new CleanWebpackPlugin(),

]

這支plugin會在打包時幫我們清空輸出資料夾內所有檔案, 再產生新的, 由於我們在設定中的output設定為dist, 因此他會清空dist

也可以清空多個資料夾

1
2
3
4
5
6
7
8
9
// 引入
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// 加到plugins區塊
// plugin 陣列
plugins: [
new CleanWebpackPlugin(),

]

htmlwebpackplugin

由於前面使用了md5的方式來命名js, 現在我們的瀏覽器無法找到正確的js檔案來載入

現在載入的是bundle.js, 但實際上已經不叫這個檔名了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack tutorial!!!</title>
<link rel="stylesheet" href="./dist/style.css">
</head>
<body>


<script src="./dist/bundle.js"></script>

</body>
</html>

解決的方法就是要讓html自動載入正確檔名的js

可以使用htmlwebpackplugin來解決

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const HtmlWebpackPLugin = require('html-webpack-plugin');

plugins: [
new TerserPlugin(),
//參考 (https://webpack.js.org/plugins/mini-css-extract-plugin/)
new MiniCssExtractPlugin({
filename: 'style.css',
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [
// 清空output資料夾裡面所有東西, 巢狀資料夾也清
"**/*",
// output之外要用絕對路徑
// process.cwd => https://kknews.cc/zh-tw/code/6nz29vm.html
path.join(process.cwd(), 'build/**/*'),
]
}),
new HtmlWebpackPLugin(),

]

這支plugin會在dist資料夾中新增一支引入正確js的index.html

dist/index.html

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width, initial-scale=1"><link href="dist/style.css" rel="stylesheet"></head>
<body>
<script src="dist/bundle.c1e009c82c2c8bf1a739.js"></script></body>
</html>

這支html有一個問題, 他引入的bundle.js路徑是錯誤的, 因為他們同樣位在dist資料夾下, 路徑不應該是dist/bundle.c1e009c82c2c8bf1a739.js, 這樣代表載入的是dist資料夾下的dist資料夾中的bundle.js
這個路徑是根據之前設定過的publicPath屬性算出來的, 現在可以把他修改成""空字串, 也就是從根目錄開始計算路徑

現在我們可以使用webpack產生出的index.html作為網頁了

在使用github pages時, 預設會使用根目錄底下的index.html檔作為網頁的入口, 但是若是使用目前的webpack設定的話, 由於index.html會在dist之下, 就無法被github pages找到(除非修改路徑)

還有另一個問題是, WEBPACK產生出的index.html也被改名為webpack app了, 這也不是我們要的

可以透過傳參數進htmlwebpackplugin來解決

1
2
3
4
5
6
7
8
new HtmlWebpackPLugin({
title: "hello webpack",
filename: "../index.html",
meta: {
description: "description text!!"
}

}),

要注意, filename是產生出的檔案名稱, 這個檔案預設會產生在設定好的output path, 也就是dist資料夾中, 但是也可以傳入相對路徑, 來改變產生的位置

htmlwebpackplugin的官方網站列出其他可客製化的屬性

中秋連假沉迷玩game無法自拔……………….

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×