也是在umi 社区看到一个比较有意思的事情,记录下
说到高级语法,不得不看下,目前tc 39
更新ECAMSCript
到哪里了,于是我翻了下finished-proposals , 好家伙, es2024(es15)出来了,
由于是新出来的API,浏览器支持的版本自然会比新。 一般Chrome和Firefox会比较快更新,但是Safari就比较慢了。
所以我们需要做兼容,通常是用babel转换语法,使用[polyfill]来兼容新的API,比如corejs
其他现代浏览器支持
一个用babel 支持 es6语法转发的webpack配置
ts
const path = require("path");
module.exports = {
entry: ["./src/index.js"],
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: 3,
},
],
],
},
},
},
],
},
};
在umi中,不会用babel对node_modules 进行转换, 如果已经某些特定产物的是es6的产物的话,那么可以通过extraBabelIncludes
来编译npm包或目录
arduino
// .umirc.ts
export default {
extraBabelIncludes: ['monaco-editor'],
}
对应的输出的webpack配置
json
{
"test": {},
"include": [
[
"/node_modules/.pnpm/registry.npmjs.org+monaco-editor@0.44.0/node_modules/monaco-editor",
null
]
],
"use": [
{
"loader": "/node_modules/.pnpm/registry.npmjs.org+@umijs+bundler-webpack@4.0.89_typescript@5.3.2_webpack@5.89.0/node_modules/@umijs/bundler-webpack/compiled/babel-loader/index.js",
"options": {
"sourceType": "unambiguous",
"babelrc": false,
"configFile": false,
"cacheDirectory": false,
"browserslistConfigFile": false,
"targets": { "chrome": 80 },
"presets": [
[
"/node_modules/.pnpm/registry.npmjs.org+@umijs+babel-preset-umi@4.0.89/node_modules/@umijs/babel-preset-umi/dist/index.js",
{
"presetEnv": {},
"presetReact": { "runtime": "automatic" },
"presetTypeScript": {},
"pluginTransformRuntime": {},
"pluginLockCoreJS": {},
"pluginDynamicImportNode": false,
"pluginAutoCSSModules": true
}
]
}
],
"resolve": { "fullySpecified": false }
},
umi对应的源码位置
之前运行 umi build
,非常慢,如果添加多个extraBabelIncludes
那就死翘翘了
umi4压缩js,默认使用的是esbuild ,据说会将es5->es6 ,但是我没真的试过,所以面对低版本的浏览器,即使配置targets
也没用,必须要需要一起改压缩器, 听说 umi5(用rust写)
会去掉esbuild
umi4给出jsMinifiter(webpack)
有多种压缩方式, esbuild
是默认值
jsMinifier (webpack)
- 类型:
string
,可选值esbuild
,terser
,swc
,uglifyJs
,none
- 默认值:
esbuild
配置构建时压缩 JavaScript 的工具;none
表示不压缩。
示例:
css
{
jsMinifier: 'esbuild'
}
jsminifieroptions
- 类型:
object
- 默认值:
{}
jsMinifier
的配置项;默认情况下压缩代码会移除代码中的注释,可以通过对应的 jsMinifier
选项来保留注释。
示例:
js
{
jsMinifier: 'esbuild',
jsMinifierOptions: {
minifyWhitespace: true,
minifyIdentifiers: true,
minifySyntax: true,
}
}
配置项需要和所使用的工具对应,具体参考对应文档:
设置tragets
targets
- 类型:
object
- 默认值:
{ chrome: 80 }
配置需要兼容的浏览器最低版本。Umi 会根据这个自定引入 polyfill、配置 autoprefixer 和做语法转换等。
示例,
js
// 兼容 ie11
targets: {
ie: 11,
}
好奇这个自定引入 polyfill、配置 autoprefixer 是怎么做的,预计源代码
生成polyfill.ts
注意:从Babel 7.4.0开始,@babel/polyfill
已被弃用,建议直接包含所需的core-js
版本和regenerator-runtime/runtime
,具体配置可以参考Babel官方文档。
IE支持
leagcy
1、 开启 legacy 参数
css
legacy: {}
开启这个参数,无疑会增加构建时间,因为他会对node_modules
进行转化, 一般不这么做
2、legacy mode
这种方式你要知道哪些包只提供es6的包
dart
// .umirc.ts
export default {
legacy: {
nodeModulesTransform: false
},
extraBabelIncludes: [
'some-es6-pkg',
/@scope//
]
}
3、 提高兼容的鲁棒性
- 按需要生成poly fill ,polyfill.io/
arduino
// .umirc.ts
export default {
headScripts: [
'http://polyfill.alicdn.com/v3/polyfill.min.js' // or https://polyfill.io/v3/polyfill.min.js
],
legacy: {}
}
- 人工core-js
利用 core-js 系工具,如通过 core-js-builder 构建自己需要的 polyfill 产物,再以 前置 script 脚本 形式引入项目。
源码位置legacy