静态转换 · 隔离执行
只读懂程序,不运行程序。
陌生 JavaScript 只是为了变得可读,不该先获得执行权限。DevSexy 会让源码经过 parser、AST 和 Prettier printer 或 Terser;不会把它交给 eval,也不会导入或运行其中的模块。
01
JavaScript 源码
02
Babel parser
03
抽象语法树(AST)
04
Prettier 或 Terser
代码执行没有入口
不会调用 eval、Function constructor,不导入用户模块、不注入 DOM,也不会触发源码里的运行时副作用。
语法通行证
按文档语法选择 parser。
Babel 适合现代 JavaScript;Babel-Flow 额外识别 Flow 类型标注。选择 Flow parser 只代表能解析这种语法,不会进行类型检查。
ES module
export { load } from './api.js'Babel · Flowasync / await
const value = await load()Babel · Flow可选链
profile?.team?.nameBabel · Flowclass field
class Store { ready = false }Babel · Flow模板字符串 / 正则
`/users/$` · /a+b/giBabel · FlowFlow 类型标注
function 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 压缩依赖的假设,需要在发布前复核。
直接 eval字符串代码可能依赖当前作用域的局部变量名谨慎启用 mangle,并单独测试相关作用域
动态属性访问运行时字符串键可能属于外部协议本页不启用或承诺 property mangling
许可证注释法律声明可能要求完整保留这里只保留 /*! 开头的注释,发布前检查许可证
Module 模式import/export 会自动启用 module 假设,也可手动开启它不是 bundler,也不做跨模块 tree-shaking
Source map内联 map 可能携带 sourcesContent 和源码公开部署前检查是否应嵌入原始源码
解析错误记录
遇到非法 token,只给诊断,不尝试执行。
Unexpected token · 第 2 行
const user = { name: 'Ada' };
if (user?.name {
console.log(user.name);
}条件以 ( 开始,却在遇到 { 前没有对应的 )。应先补全条件括号;后续报错位置可能只是连锁结果。