版本
一、Webpack 4.x
二、Webpack 5.x
2.1 启动命令
2.2 持久化缓存
Webpack5 新增cache
,用于缓存生成的webpack模块和chunk,改善构建速度。Webpack5追踪了每个模块的依赖,并创建了文件系统快照。此快照会与真实文件系统进行比较,当检测到差异时,将触发对应模块的重新构建。
2.3 资源模块
资源模块 是一种模块类型,它允许使用资源文件(字体、图标、图片等)而无需配置额外的**loader
**
-
raw-loader
=>asset/source
导出资源的源代码 -
file-loader
=>asset/resource
发送一个单独的文件并导出URL
-
url-loader
=>asset/inline
导出一个资源的Data URI
-
asset
=> 在导出一个Data URI
和发送一个单独的文件之间自动选择。之前通过使用url-loader
,并且配置资源体积限制实现
2.4 moduleIds 和 chunkIds 的优化
**module
为每一个文件都可以看成一个 module
。chunk
**为 Webpack
打包最终生成的代码块,代码块会生成文件,一个文件对应一个 chunk
。在生产模式下,默认启用chunkIds:"deterministic"
,moduleIds:"deterministic"
,此算法采用确定性的方式将短数字 ID
(3个或4个字符)短 **hash
**值分配给 **modules
**和 chunks
。
对于moduleIds
而言:
- 开发模式下:
moduleId
是相对于根目录的相对路径。这种方式的好处就是容易让人立即,一眼就看出来是哪个文件。缺点就是moduleId
太长,增加了文件体积,有时候moduleId
还可能是一个敏感文件,容易暴露信息 - 生产模式下:
对于chunkIds
而言:
-
开发模式下:
-
生产模式下:
webpack.config.js
通过optimization
配置moduleIds
与chunkIds
const Path = require("path");
module.exports = {
mode: "development",
entry: Path.resolve(__dirname, "src", "index.js"),
cache: {
type: "filesystem",
cacheDirectory: Path.resolve(__dirname, "node_modules/.cache/webpack"),
},
output: {
filename: "index.js",
path: Path.resolve(__dirname, "build"),
},
optimization: {
moduleIds: "deterministic",
chunkIds: "deterministic",
},
};
2.5 更智能的 Tree Shaking
Webpack4
本身的 Tree Shaking
比较简单,主要是找一个 import
进来的变量是否在这个模块中出现过。Webpack5
可以进行根据作用域之间的关系来进行优化。
2.6 nodeJs 的 Polyfill 脚本移除
Webpack4
带了许多 Node.js
核心模块的 polyfill
,一旦模块中使用了任何核心模块(如crypto
),这些模块就会被自动启用。Webpack
不再自动引入这些 polyfill
。
理解: 比如说在webpack5
中使用crypto-js
依赖库,crypto-js
其中用到了 **Node
**中的crypto
模块,那么我们现在要手动通过resolve.fallback
来引入这个模块
resolve:{
fallback:{
crypto: require.resolve('crypto-browserify'),
}
},
2.7 模块联邦
模块联邦(Module Federation
) 的动机是为了不同开发小组间共同开发一个或者多个应用。应用将被划分为更小的应用块。一个应用块,可以是比如头部导航或者侧边栏的前端组件,也可以是数据获取逻辑的逻辑组件,每个应用块由不同的组开发。应用或者应用块共享其他应用块或者库。
模块联邦(Module Federation
) ,每个应用块都是一个独立的构建,这些构建将编译为容器。容器可以被其他应用或者其他容器应用。一个被引用的容器被称为 remote
,引用者被称为 host
,**remote
**暴露模块给 host
, **host
**则可以使用这些暴露的模块,这些模块被称为 **remote
**模块。
配置参数
-
name
: 必传值,即输出的模块名,被远程引用时路径为${name}/${expose}
-
library
: 声明全局变量的方式,name
为umd
的name
-
filename
: 构建输出的文件名 -
remotes
: 远程引用的应用名及其 别名的映射,使用时以 **key
**值作为name
-
exposes
: 被远程引用时可暴露的资源路径及其别名。注意: 该项目作为remote
时,通过exposes
暴露模块 -
shared
: 与其他应用之间可以共享的第三方依赖,使你的代码中不用重复加载同一份依赖。注意: 如果该项目作为remote
,那么shared
才有意义,配置才有效;项目只作为host
时配置shared
没有任何意义。
具体实现
-
项目一: 作为
remote
被其他项目引用,作为host
引用其他项目-
module1/webpack.config.js
const Path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MFP = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
mode: "development",
entry: Path.resolve(__dirname, "src", "index.js"),
output: {
filename: "index.js",
path: Path.resolve(__dirname, "build"),
},
devServer: {
port: 8001,
},
plugins: [
new HtmlWebpackPlugin({
template: Path.resolve(__dirname, "index.html"),
}),
new MFP({
name: "module1",
filename: "module1Entry.js",
remotes:{
module2:'module2@http://localhost:8002/module2Entry.js'
},
exposes: {
"./module": "./src/module.js",
},
shared: {
lodash: { singleton: true },
},
}),
],
}; -
module1/src/index.js
import('./bootstrap');
-