Webpack5 的一些知識總結
前言
webpack 5 是 2020 年發佈的,webpack 4 是 2018 年發佈的,在 webpack 4 之上也做出了挺多的改變,比如,添加了 cache 的支持,模塊聯邦新玩意......
持久性緩存來提高構建性能
在 webpack 5 之前,webpack 是沒有提供持久化緩存,我們開發的時候需要使用類似 cache-loader 來做緩存方面的處理。
在 webpack 4 中:
module.exports = {
module: {
rules: [
{
test: /.ext$/,
use: ['cache-loader', ...loaders],
include: path.resolve('src'),
},
],
},
};
在 webpack 5 中
在 webpack 5 中自身也加入了持久化緩存,緩存生成的 webpack 模塊和 chunk,來改善構建速度。cache 會在開發 模式被設置成 type: 'memory' 而且在 生產 模式 中被禁用。
module.exports = {
cache: {
type: 'filesystem',
},
};
cache.type 有兩個值 memory | filesystemmemory 表示會將打包生成的資源存放於內存中。filesystem 表示開啓了文件系統緩存。
更好的 hash 算法
這裏指的就是訪問 web 頁面時的瀏覽器緩存,我們也知道,之前有 hash chunckhash contenthash 在 webpack 5 中,把 hash 改成了 fullhash。
首先,我們介紹一下這幾個 hash 值有什麼不一樣。
hash/fullhash
hash/fullhash 是根據打包中的所有文件計算出來的 hash 值,在一次打包中,所有的資源出口文件的 filename 獲得的 [hash] 都是一樣的。
chunckhash
chunckhash 顧名思義是根據打包過程中當前 chunck 計算出來的 hash 值。
contenthash
contenthash 顧名思義是根據打包時的內容計算出的 hash 值。
當然,這麼看好像,看不出啥問題,不就是把一個 hash 改成 fullhash 而已嘛?dang dang dang 然不是,我們就來扒扒看,直接上實戰,喵喵有啥不一樣。
我們先設定 webpack 的設置如下
const path = require('path');
module.exports = {
mode: 'production',
entry: {
index: './index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[contenthash].js',
},
}
這裏是要打包的 index.js 的內容
const num = 1;
console.log('這裏是輸出', num);
這是添加註釋和修改變量後的 index.js 的內容
const str = 1;
//這裏是輸出
console.log('這裏是輸出', str);
webpack 4 打包
我們可以看到這裏的 hash 值爲 e8510378c5f44d16af40 。
這裏是添加註釋和修改變量後打包後的結果
我們可以看到這裏的 hash 值爲 2c719bba27df586bf8f2 。
webpack 5 打包
我們可以看到這裏的 hash 值爲 d1bc13ae7e7dc828a64f 。
這裏是添加註釋和修改變量後打包後的結果
我們可以看到這裏的 hash 值爲 d1bc13ae7e7dc828a64f 。
總結
我們可以明顯看出,webpack 4 對於添加註釋和修改變量其實,是會影響它的一個 contenthash 值的計算,如果是 webpack 5 的話,就不會影響。
Tree Shaking 的改進
tree shaking 是一個術語,通常用於描述移除 JavaScript 上下文中的未引用代碼 (dead-code)。它依賴於 ES2015 模塊語法的 靜態結構 特性,例如 import 和 export。
既然 webpack 4 都有這個功能,那麼隨着 webpack 5 的升級,又有什麼不一樣的地方呢?
我們來建立一個三個文件,index.js、a.js、b.js
// a.js
const name = 'zhangSan';
const age = 18;
export { name, age };
// b.js
import * as data from'./a';
export { data };
// index.js
import * as common from'./b';
// 我們可以看到只是使用了 age,而沒有使用 name
console.log(common.data.age);
webpack 4 打包結果
但是我們打包出來的結果,卻是連 name 也打包進去。
webpack 5 打包結果
簡直完美秒殺。
總結
當然,在 webpack 4 中,Tree Shaking 對嵌套的導出模塊未使用代碼無法很好進行 Tree Shaking,當然我們也可以藉助一些 plugin 來實現,但是到了 webpack 5 得到了很大的改進。
模塊聯邦(Module Federation)
Webpack5 模塊聯邦讓 Webpack 達到了線上 Runtime 的效果,讓代碼直接在項目間利用 CDN 直接共享,不再需要本地安裝 Npm 包、構建再發布了!
容器項目
//這裏是容器的webpack模塊聯邦設置【也就是在該組件使用】
newModuleFederationPlugin({
name: 'react1',
library: { type: 'var', name: 'react1' },
remotes: {
RemoteComponent: 'RemoteComponent'
},
}),
// 在html引入
<script src="http://localhost:3001/remoteEntry.js"></script>
// 這裏是它的代碼
importReact, { Fragment } from'react';
importReactDOMfrom'react-dom';
constButton = React.lazy(() =>import('RemoteComponent/Button'));
functionApp() {
functiononClick() {
console.log('這裏是遠程組件觸發的');
}
return (
<div>
<h1>這裏是測試模塊聯邦的項目</h1>
<React.Suspense fallback='努力加載中💪...'>
<Button onClick={onClick} content='content'></Button>
</React.Suspense>
</div>
);
}
遠程組件項目
// 提供遠程組件的項目webpack模塊聯邦設置
newModuleFederationPlugin({
name: 'RemoteComponent',
library: { type: 'var', name: 'RemoteComponent' },
// 使用此遠程組件加載的文件名稱
filename: 'remoteEntry.js',
exposes: {
//此處提供了一個Button組件
'./Button': './src/components/Button',
},
}),
// 這是遠程button組件
importReactfrom'react';
exportdefaultfunctionButton({ content, onClick = () => {} }) {
return (
<button onClick={onClick}>{ content }</button>
)
}
實際效果
我們可以看到,點擊按鈕,成功觸發 onClick 事件。
Asset Modules
Asset Modules 通常被翻譯爲資源模塊,它指的是圖片和字體等這一類型文件模塊,它們無須使用額外的預處理器,webpack 通過一些配置就可以完成對它們的解析。
在 webpack 5 之前,沒有內置資源模塊,所以,我們通常使用,file-loader url-loader raw-loader 之類的 loader 去處理。
// 在webpack5中,可以直接使用內置的資源模塊就行了
module.exports = {
// ...
module: {
rules: [{
test: /\.jpg$/,
type: 'asset/resource'
}]
}
}
// 在webpack 4就需要使用 file-loader 之類的loader
module.exports = {
module: {
rules: [
{
test: /.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
}
]
}
}
Asset Modules 它的值有四種,asset/resource(對應 file-loader)、asset/inline(對應 url-loader)、asset/source(對應 raw-loader)、asset。
結束
當然,webpack 5 的改變不止這些,比如,還有 不再爲 Node.js 模塊自動引用 polyfill、也內置了 terser 進行代碼壓縮......
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/l06gQrTw67X6mxeE2iJkgQ