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",
}
})
],
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端