静态转换 · 隔离执行
只读懂程序,不运行程序。
陌生 JavaScript 只是为了变得可读,不该先获得执行权限。DevSexy 会让源码经过 parser、AST 和 Prettier printer 或 Terser;不会把它交给 eval,也不会导入或运行其中的模块。
JavaScript 源码
Babel parser
抽象语法树(AST)
Prettier 或 Terser
不会调用 eval、Function constructor,不导入用户模块、不注入 DOM,也不会触发源码里的运行时副作用。
语法通行证
按文档语法选择 parser。
Babel 适合现代 JavaScript;Babel-Flow 额外识别 Flow 类型标注。选择 Flow parser 只代表能解析这种语法,不会进行类型检查。
export { load } from './api.js'Babel · Flowconst value = await load()Babel · Flowprofile?.team?.nameBabel · Flowclass Store { ready = false }Babel · Flow`/users/$` · /a+b/giBabel · Flowfunction f(value: string): numberFlow parser同一份源码,两种输出目的
便于审阅的代码和便于交付的代码,不是同一个任务。
格式化
审阅export async function load(id) {
const response = await fetch(`/items/${id}`);
return response.json();
}- 变量名保持可读
- 由 Prettier 统一缩进、换行与打印风格
- 只重排源码,不执行函数或模块
压缩
交付export async function load(t){const n=await fetch(`/items/${t}`);return n.json()}- 开启 mangle 时,局部变量名可能改变
- 除 /*! 开头的注释外,大多数注释会移除
- 可选生成内联 source map,并决定是否嵌入原始源码
压缩风险清单
Terser 压缩依赖的假设,需要在发布前复核。
解析错误记录
遇到非法 token,只给诊断,不尝试执行。
const user = { name: 'Ada' };
if (user?.name {
console.log(user.name);
}条件以 ( 开始,却在遇到 { 前没有对应的 )。应先补全条件括号;后续报错位置可能只是连锁结果。