背景
日常开发中,有时会存在漏掉代码进行 babel 转换,或者是直接引用了未经过 babel 转换的第三方代码库中的 js 文件,很显然,这会导致页面在部分机型报错甚至页面白屏
为了解决上述问题,产出了 mpx-es-check 工具,用来对构建产物代码进行分析,检测其中是否有低版浏览器不支持的语法。
使用
install
npm i mpx-es-check --save-dev
// or
npm i mpx-es-check -g
Usage
- 如果是本地安装:在 package.json 中添加 scripts 命令
"esCheck": "mpx-es-check --module --ecma=6 './dist/*.js'"
- 如果是全局安装:可直接运行命令
mpx-es-check --module --ecma=6 ./dist/*.js
- --module
默认以 script 检测代码
- es6
- 所需要检测的最低版本,输入es6 表示会检测 es6及以上的所有语法
- ./dist/*.js
- 设置文件匹配的范围: ./somePath/*.js
- --all
- 在命令中添加 --all 参数会启用实例方法和静态方法的检测
mpx-es-check --module --all --ecma=6 ./dist/*.js
result
- 如果检测到存在高版本语法或方法,则会在终端输出 error 提示 log,并会在检测文件目录生成 es-check.log 文件,进行详细错误信息的查看,log 文件中会输出
// 终端输出
检测进度:100.00% ████ 4/4
检测到语法错误, 详情请查看文件:
/Users/some/Project/babel-test/mpx-es-check/dist/es-check.log
// es-check.log
ERROR:
Using const is not allowed
at file: ./dist/test2.js
at startLine: 1
at startColumn: 0
ERROR:
Using const is not allowed
at file: ./dist/test4.js
at startLine: 2
at startColumn: 0
原理
parse
将构建产物代码使用 babel/parse 转成ast
traverse
- 首先根据用户命令行输入的 es 版本进行检测规则的整合
这里有创建一个 eventEmitter,将检测规则进行注册,同时检测规则中,ecma 语法部分是依据与 estree 进行的配置 instance method 和 static method,以及 BuiltIns Object 是依照 transform-runtime 中 runtime-corejs3-definitions 进行配置,这里列举一个简单的示例:
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = () => {
return {
BuiltIns: {
Map: {
stable: true,
path: "map"
}
},
StaticProperties: {
Array: {
from: {
stable: true,
path: "array/from"
},
isArray: {
stable: true,
path: "array/is-array"
},
of: {
stable: true,
path: "array/of"
}
},
},
InstanceProperties: {
concat: {
stable: true,
path: "concat",
types: ["array"]
}
}
};
};
exports.default = _default;
- 在代码里对这部分语法规则进行检测规则的注册:
module.exports = {
meta: {
docs: {
description: 'ecma2017 rules'
}
},
create (context) {
return {
// 检测 async
FunctionDeclaration (node) {
if (node.async === true) {
context.report({
node,
message: 'Using async function is not allowed'
})
}
},
// 检测 await
AwaitExpression (node) {
if (node.operator === '**=') {
context.report({
node,
message: 'Using AwaitExpression await is not allowed'
})
}
}
}
}
}
方法和内建对象的检测是通过 MemberExpression 节点中,(object.name)[proterty.name] 是否匹配规则进行检测。 不过这种检测方法会存在误诊的情况,例如 引入的 core-js/pofyfill 中会存在一些 if 判断或者是 或 运算符:
var nativeAssign = Object.assign || _pofillAssign
会导致 es-check 产生方法的误判,目前也在逐步的完善对方法的整体语法环境的判断,暂时只实现了 在 ifStatement 中规避检测的方法。同时因为方法检测的不确定性,这一部分功能也添加了 --all 选项来供用户自由选择是否打开。
- 对整个 ast 树进行遍历,这里使用的 babel/traverse
在遍历节点树的过程中,当遇到 eventEmitter 中已经注册过的节点,则进行 rule 的执行
applySelector (node, selector, path) {
if (esquery.matches(node, selector.parsedSelector, this.currentAncestry)) {
this.emitter.emit(selector.rawSelector, node, path)
}
}
error
匹配到相应的 ast 节点,通过report 函数进行 error/warning 上报,最终收集输出到 es-check.log 文件中
总结
使用 mpx-es-check 基本上能够避免应用因为语法兼容问题导致的故障。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!