前言
webpack 5是2020年发布的,webpack 4是2018年发布的,在webpack 4之上也做出了挺多的改变,比如,添加了cache的支持,模块联邦新玩意......
持久性缓存来提高构建性能
在webpack 5之前,webpack是没有提供持久化缓存,我们开发的时候需要使用类似 cache-loader 来做缓存方面的处理。
在webpack 4中:
代码语言:javascript复制module.exports = {
module: {
rules: [
{
test: /.ext$/,
use: ['cache-loader', ...loaders],
include: path.resolve('src'),
},
],
},
};
在webpack 5中
在webpack 5中自身也加入了持久化缓存,缓存生成的 webpack 模块和 chunk,来改善构建速度。cache 会在开发 模式被设置成 type: 'memory' 而且在 生产 模式 中被禁用。
代码语言:javascript复制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的设置如下
代码语言:javascript复制const path = require('path');
module.exports = {
mode: 'production',
entry: {
index: './index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[contenthash].js',
},
}
这里是要打包的 index.js 的内容
代码语言:javascript复制const num = 1;
console.log('这里是输出', num);
这是添加注释和修改变量后的 index.js 的内容
代码语言:javascript复制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
代码语言:javascript复制// a.js
const name = 'zhangSan';
const age = 18;
export { name, age };
代码语言:javascript复制// b.js
import * as data from './a';
export { data };
代码语言:javascript复制// 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 包、构建再发布了!
容器项目
代码语言:javascript复制//这里是容器的webpack模块联邦设置【也就是在该组件使用】
new ModuleFederationPlugin({
name: 'react1',
library: { type: 'var', name: 'react1' },
remotes: {
RemoteComponent: 'RemoteComponent'
},
}),
代码语言:javascript复制// 在html引入
<script src="http://localhost:3001/remoteEntry.js"></script>
代码语言:javascript复制// 这里是它的代码
import React, { Fragment } from 'react';
import ReactDOM from 'react-dom';
const Button = React.lazy(() => import('RemoteComponent/Button'));
function App() {
function onClick() {
console.log('这里是远程组件触发的');
}
return (
<div>
<h1>这里是测试模块联邦的项目</h1>
<React.Suspense fallback='努力加载中