1. webpack5的解構代碼打包方式
針對下面文件進行打包.
// moduleA
export default {
a: 1,
}
// index.js
import moduleA from "./moduleA";
console.log("hello webpack", moduleA);
webpack5的打包結果, 就這28行. 但是webpack4有300多行. 300多行里很多是 引入函數import的實現,
但是在webpack5這里, 由于發現moduleA里是靜態文件,可以直接拷貝過去, 所以沒有import的實現.
就是說webpack5的打包結果會根據項目具體情況, 使用解構的方式, 只打包必須用的代碼, 而不是像webpack4一樣,打包所有可能用的代碼.
(() => {
var r = {
208: () => {
"use strict";
console.log("hello webpack", {
a: 1
})
},
956: r => {
r.exports = {
entry: "./src/index.js",
mode: "production"
}
}
},
e = {};
function o(t) {
var s = e[t];
if (void 0 !== s) return s.exports;
var n = e[t] = {
exports: {}
};
return r[t](n, n.exports, o),
n.exports
}
o(208),
o(956)
})();
2. webpack5,webpack4的緩存cache
相同代碼
webpack5
- 未緩存, 2233ms
- 緩存, 未修改業務代碼, 157ms
- 緩存, 修改了業務代碼, 386ms
webpack4
- 未緩存, 2423ms
- 緩存, 未修改業務代碼, 360ms
- 緩存, 修改了業務代碼, 360ms
對比總結
- webpack5 比 webpack4的文件壓縮策略更優, 分割文件后的vendor體積更小
- webpack5 緩存構建性能優于webpack4
- webpack5 緩存的功能顯著優于webpack4.
3. Webpack5的URIs.
webpack5支持在請求中處理協議
- 支持data, 支持base64或原始編碼, Mimetype可以在module.rule中被映射到加載器和模塊類型. 例如
import x from "data:text/javascript, export default 42"(data:text/javascript 表示js代碼) - 支持file, 支持引入本地資源文件(飛項目中資源)
- 支持http(s), 需要通過
new webpack.experiments.schemesHttp(s)UriPlugin()選擇加入, 默認情況下, 當目標位web時, 這些URI會導致對外部資源的請求
// data
import data from "data:text/javascript, export default 'hello webpack'";
console.log(data); // hello webpack;
// file, 從絕對路徑獲取文件.(非當前項目目錄的文件)
import dataFile from "file:///Users/liumeng/desktop/a.txt"
// https, 需要再webpack.config.js里配置, allowwebUris屬性,允許https的請求
import img from "https://xxxx/xx.png"
4. webpack5 更好的treeshaking
- 如果module導出的是簡單數據類型,比如數字,字符串,boolean, webpack5會直接把這個簡單數據類型直接, 替換到對應使用位置, 去掉導出的邏輯. 減少了相關代碼.
// moduleA
export default {
a: 1,
b: function() {console.log(123)}
}
// index.js
import { a } from "moduleA.js";
console.log(a)
// index.js build之后,會直接把a的值拿出來,放到變量a里面, 從而去掉引入的過程.實現更好的treeshaking
console.log(1);
- 如果導入內容未使用,則webpack5不會打包. webpack4則會打包進去.
如果用import "a.js", 如果a.js里什么都沒做, webpack5不會導入a.js, webpack4依舊會導入a.js
總之webpack5的treeshaking更加的智能.
// 只導入了vue, 沒有使用.
import vue from 'vue';
console.log(123)
// webpack5會把vue的內容去掉.
console.log(123)
// webpack4,會把vue的內容打包進去.
- sideEffects 控制treeshaking
sideEffects:
- package.json的屬性
- 控制treeshaking的程度, 如果為true, 則認為代碼有用, 不會被treeshaking掉. false,則是最大程度的treeshaking. 能去掉都去掉.
- 可以使boolean,也可以是數組,
["./src/lib.js"],表示該文件有用,不能被treeshaking掉.
{
// package.json
"sideEffects": true, // false
}
5. webpack5支持package.json的 exports 屬性
js可以在node環境和瀏覽器web環境運行. 有些工具庫也確實需要支持這兩個環境, 比如工具庫 lodash
但是在node和web中原生對象是不同的. node能用require, fs, path, os. web能用import,document, window.這就需要分開處理.
就是說同一個工具,node,web環境的代碼是不同的, 需要不同的版本.原來是需要我們自己去判斷的.
package.json的 exports 就解決了這個問題. 對應環境自動使用對應版本的代碼,不用我們自己做判斷了.
// package.json
{
"exports": {
// 如果能用require,說明是node環境, 則用a.js為入口文件
"require": "./a.js",
// 如果能用import, 說明是web環境,則用b.js為入口.
"import": "./b.js"
}
}
該特性只有webpack5支持, webpack4暫不支持.
6. module federation 模塊聯邦
模塊聯邦是 webpack5新內置的一個重要功能, 可以讓跨應用間真正做到模塊共享,
webpack5新增 module Federation功能, 可以幫助多個獨立的構建組成一個應用程序,不同的構建可以獨立開發與部署.
可以實現微前端.
項目示例: 微應用: webpack-new-feature/demo2/app_a ; 主應用: webpack-new-feature/demo2/app_b
微應用app_a
下面的代碼, 用npm run serve啟動后, 可以從http://127.0.0.1:3000/app_a.js看到打包后的index.js代碼.
注意: 默認的文件名是main.js,但是我們設置了filename:"app_a.js"就把請求地址改了.
// index.js
function run() {
console.log("子應用啟動app_a中...");
return "run";
}
export default run;
// webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
export default {
plugins: [
new ModuleFederationPlugin({
// 沒有filename時, 文件路徑默認是 localhost:3000/main.js,
// 設置了filename后,文件路徑是 localhost:3000/app_a.js
filename: "app_a.js",
// 對外名稱為main, 別的地方引入時用 import("main/moduleA").
name: 'appA',
exposes: {
// main下面的子模塊
'./moduleA': './index.js',
}
})
],
}
// package.json
{
"serve": "webpack serve --config ./webpack.config.js"
}
主應用app_b
先啟動app_a, 再啟動app_b,就能再app_b的代碼中引用app_a的模塊. 例子: 壹錢包的mice就是主應用, 簽到系統就是微應用. 先啟動簽到系統項目,再啟動mice,就能再mice里通過地址看簽到系統的效果了
// 主應用業務代碼
console.log("主應用app_b啟動主");
import("appA/moduleA").then((res) => {
const run = res.default;
console.log(run());
})
// webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
export default {
plugins: [
new ModuleFederationPlugin({
filename: "app_b.js",
name: "app_b",
// 引入的微應用.
remotes: {
// 微應用名稱@微應用文件地址
appA: "appA@http://localhost:3000/app_a.js",
}
})
],
}
浙公網安備 33010602011771號