部分安卓设备App崩溃报块级声明不支持错误,求webpack/babel适配方案
问题根因
Android API 23及更低版本对应的WebView内核为Chrome 44及更旧版本,正是这类旧版JS引擎的特性限制触发了报错:
Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
限制具体分为两点:
- 仅原生支持ES5标准语法,默认不识别let/const/class等ES6+新增的块级声明语法
- 即便部分版本对块级声明做了兼容,也仅允许在严格模式下运行,非严格模式下直接抛出异常
所需Babel配置
通过Babel可以完成ES6+语法到ES5的转译,同时自动注入严格模式声明,适配旧版WebView:
- 首先安装必要依赖
npm install @babel/preset-env @babel/plugin-transform-strict-mode @babel/preset-react core-js@3 --save-dev - 在项目根目录新增或修改
.babelrc(或babel.config.json)配置文件:
{ "presets": [ ["@babel/preset-env", { "targets": { "android": "23", "chrome": "44" }, "useBuiltIns": "usage", "corejs": 3 }], "@babel/preset-react" ], "plugins": [ "@babel/plugin-transform-strict-mode" ] }
targets配置会明确指定转译的适配目标,所有超出Android 23/Chrome44支持范围的语法都会被转成ES5兼容写法@babel/plugin-transform-strict-mode会自动在所有JS文件头部注入'use strict'声明,让块级声明可以在旧引擎下正常运行useBuiltIns配合corejs会自动按需注入Polyfill,兼容旧环境下缺失的ES6+ API
webpack对应配置
需要在webpack规则中指定babel-loader处理相关文件,避免第三方依赖的ES6语法未被转译:
- 安装babel-loader依赖
npm install babel-loader --save-dev - 修改webpack配置文件的
module.rules部分:
module.exports = { // 其余webpack配置项保持不变 module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules\/(?!(react|react-dom)\/)/, use: 'babel-loader' } ] } }
exclude配置排除了node_modules下大部分不需要转译的包,仅保留react、react-dom等需要兼容旧环境的库进行转译,既降低打包开销,也避免第三方依赖的ES6语法未被转译导致报错
效果校验
打包完成后可以抽取最终生成的JS文件检查:
- 搜索是否还有未被转译的
let/const/class关键字,确认都被转成了var或者被包裹在严格模式代码块中 - 确认文件头部存在
'use strict'声明
内容的提问来源于stack exchange,提问作者user3599672
相关产品推荐
相关产品推荐

