webpack4升级到webpack5,打包后在google上正常运行,IE11报错 记录两个兼容性问题的坑
Webpack config
一般情况下,第三方依赖打完包后提供给外部调用的代码都是使用的ES5语法,这也是为什么配置babel-loader时一般都忽略node_modules
文件夹,除了性能上的考虑之外,实际上大部分依赖都不需要再进行转译了
也就是说,当babel正确配置时,也只是对项目的业务代码部分进行polyfill,第三方依赖包中的语法babel管不着(如果你配了exclude: /node_modules/
)
举个babel-loader的?:
// webpack.config.js
{
//...
module: {
rules: [
{
// node_modules的依赖一般都做了编译处理,不需要再次编译
exclude: /node_modules/
test: /\.(js|jsx)$/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {targets: 'ie 11'}]
],
}
}
]
}
}
就算这么配置,你还是能在打包后的js文件中发现很多ES6的语法,比如箭头函数,在ie11上运行就直接报错
这是因为Webpack5在这一方面做了更细粒度的优化,它默认的打包结果使用的是ES6语法,如果有需要,才会根据具体的配置来生成代码,所以默认情况下,webpack5是不支持IE的,因为它默认打包出来就是使用的ES6语法
仔细阅读文档,Webpack5的配置项output.enviroment提供了一系列关于代码最终运行环境的配置,其中默认的配置项基本都不支持IE,必须手动指定为这些配置项
// 文档配置介绍
module.exports = {
output: {
environment: {
// The environment supports arrow functions ('() => { ... }').
arrowFunction: true,
// The environment supports BigInt as literal (123n).
bigIntLiteral: false,
// The environment supports const and let for variable declarations.
const: true,
// The environment supports destructuring ('{ a, b } = obj').
destructuring: true,
// The environment supports an async import() function to import EcmaScript modules.
dynamicImport: false,
// The environment supports 'for of' iteration ('for (const x of array) { ... }').
forOf: true,
// The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
module: false,
},
},
};
在output.enviroment中加入配置: 这个配置表示我们打包后的代码运行的环境是否支持这些语法,显然有一部分语法IE是不支持的,改为false
module.exports = {
// ...其他属性
output: {
environment: {
arrowFunction: false, // 环境不支持箭头函数
bigIntLiteral: false, // 不支持BigInt
const: true,
destructuring: false, // 不支持解构
dynamicImport: false, // 不支持异步import
forOf: false, // 不支持for...of
module: false, // 不支持module
},
},
};
第二个坑: JS压缩插件-TerserWebpackPlugin
JS文件被babel编译后,下一步就是压缩(生产环境),JS的压缩插件uglifyjs-webpack-plugin
已经被terser-webpack-plugin
取代,并且webpack5内置了该依赖,但是坑的一点是terser-webpack-plugin
压缩时默认也不会使用ES5语法,比如
let a = 1;
let b = {a: a}
这段代码会被压缩成:
let a=1;let b={a}
其中使用了ES6的语法糖,运行在IE会报错。
需要明确在TerserWebpackPlugin
中指定
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
ecma: 5
})],
},
};
完整相关配置代码如下:
module.exports = {
output: {
entry: 'main.js',
output: {
publicPath: '',
path: 'dist',
enviroment: {
arrowFunction: false, // 环境不支持箭头函数
bigIntLiteral: false, // 不支持BigInt
const: false, // ie 10不支持const
destructuring: false, // 不支持解构
dynamicImport: false, // 不支持异步import
forOf: false, // 不支持for...of
module: false, // 不支持module
},
filename: () => (isDev ? '[name].js' : '[name].[contenthash:8].js'),
chunkFilename: () => (isDev ? 'assets/[name].js' : 'assets/[name].[contenthash:8].js')
},
target: 'web',
resolve: {
extensions: ['ts', 'tsx', 'js', 'jsx'],
alias: {
'@': 'src',
vue$: 'vue/dist/vue.runtime.esm.js'
}
},
module: {
rules: [
// 其他的loader
{
test: /\.(js|jsx)$/,
// node_modules的依赖一般都做了编译处理,不需要再次编译
exclude: /node_modules/
use: {
loader: 'babel-loader',
// options可以抽离到babel.config.js文件,targets可以通过.browserslistrc配置
options: {
presets: [
['@babel/preset-env', {targets: 'ie 11'}]
],
}
}
}
]
},
// 一般只在Production环境下开启
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
ecma: 5
})
],
},
}
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!