下面是一份基于你刚才系统性探索的编译到 JavaScript 技术路线深度总结报告。我不会简单罗列,而是帮你把这些语言和架构抽象成几种“根本范式”,并给出工程决策层面的结论。
一、问题本质:编译到 JS 的三种核心矛盾
所有这些语言,本质都在解决三个冲突:
1. 语义 vs JS 表达能力
- 源语言通常更强(类型、并发、ADT 等)
- JS 是动态 + 单线程 + 原型模型
2. 优化 vs 语义完整
- 想优化 → 必须“压平语义”
- 想完整语义 → 必须 runtime
3. 通用性 vs 工程复杂度
- 通用 IR → 强但复杂
- 专用语言 → 简单但不通用
二、六大技术路线(统一抽象)
你看到的所有语言,可以压缩成 6种范式:
① 语言收缩型(ReScript / Gleam)
核心思想
限制语言 → 直接映射 JS / VM
Pipeline
特征
- 几乎无 runtime
- 无复杂 IR
- JS 质量极高
优点
缺点
② 语义映射型(Fable / 部分 Nim)
核心思想
强前端语义 → 映射到 JS
Pipeline
语言 → Typed AST → 语义转换 → JS
特征
- 轻 IR(甚至无 IR)
- 中等 runtime
- 强类型系统依赖前端
优点
缺点
③ IR lowering 型(Kotlin / Scala.js / MoonBit)
核心思想
语义 → IR → lowering → JS
Pipeline
语言 → Typed AST → IR → lowering → JS
特征
优点
缺点
④ IR + Linker 型(Scala.js)
核心思想
IR + 全局分析(whole-program optimization)
Pipeline
特征
- 模块级 IR
- call graph / DCE / inline
- 类似 LTO
优点
- 工业级优化
- bundle size 控制强
- 适合大型系统
缺点
⑤ runtime 模拟型(Go / ClojureScript)
核心思想
在 JS 上实现语言运行时
Pipeline
特征
- runtime 很重
- JS 只是“宿主”
- IR 不重要
优点
缺点
- 性能差
- bundle 巨大
- 不 JS-native
⑥ AST 多后端型(Haxe / Nim)
核心思想
AST 即 IR,多后端 codegen
Pipeline
语言 → Typed AST → 多 backend
特征
优点
缺点
三、统一对比矩阵(核心)
| 路线 |
IR |
runtime |
JS质量 |
优化 |
通用性 |
复杂度 |
| ReScript |
❌ |
极低 |
★★★★★ |
★★ |
低 |
★ |
| Fable |
弱 |
中 |
★★★★ |
★★ |
中 |
★★ |
| Kotlin |
强 |
中 |
★★★ |
★★★ |
高 |
★★★ |
| Scala.js |
强+Linker |
中 |
★★★ |
★★★★★ |
高 |
★★★★★ |
| Go |
❌ |
极高 |
★ |
★ |
高 |
★★★ |
| ClojureScript |
❌ |
极高 |
★ |
★ |
高 |
★★★ |
| Haxe |
❌ |
低 |
★★★ |
★★ |
中 |
★★ |
| Nim |
弱 |
中 |
★★ |
★★ |
中 |
★★ |
| MoonBit |
强 |
低 |
★★★★ |
★★★★ |
高 |
★★★★ |
四、关键设计维度(你必须做的选择)
你现在真正要决定的是这几个“轴”:
1. IR 是否是核心?
选 YES(MoonBit / Scala.js)
选 NO(ReScript / Fable)
2. runtime 要多重?
无 runtime(ReScript)
→ 最 JS-native
中 runtime(Kotlin / Fable)
→ 平衡
重 runtime(Go / CLJS)
→ 语义完整
3. 是否做 Linker?
无 linker
→ 小项目 OK
有 linker(Scala.js)
→ 工业级系统
4. 是否支持多语言?
单语言(Kotlin / MoonBit)
→ 更好优化
多语言 IR(你目标)
→ 极高复杂度
五、最重要的工程洞察(精华)
1. IR 的价值不在“翻译”,而在“统一优化空间”
没有 IR:
有 IR:
2. runtime 和 IR 是对冲关系
| IR 强 |
runtime 弱 |
| IR 弱 |
runtime 强 |
3. JS backend 的难点不在“生成代码”,而在:
- CFG 重建
- phi 消除
- 类型稳定
- object shape
- JIT 友好
4. “语言设计”比“编译器设计”更重要
ReScript 成功的原因:
不是编译器强,而是语言被限制得刚好
5. Linker 是规模化的关键
没有 linker:
6. 大部分系统失败在 runtime
- GopherJS → 太重
- ClojureScript → 不 JS-native
六、你的目标定位(关键判断)
你现在的目标是:
多语言 → JS
这意味着:
你不能选的路线
❌ ReScript
→ 不支持多语言
❌ Go / CLJS
→ runtime 爆炸
❌ Haxe / Nim
→ 优化不足
你真正的候选路线
方案 A(推荐)
Typed AST → SSA IR → JS backend
方案 B(进阶)
Typed AST → SSA IR → Linker → JS
七、最终架构建议(最重要)
结合所有语言的最佳实践,你的系统应该是:
1. 前端层(多语言)
Language A → Typed ASTLanguage B → Typed AST
2. IR 层(核心)
特征:
- block arguments(代替 phi)
- 强类型
- CFG 明确
- JS-friendly
3. 优化层
SSA IR → optimization passes
- constant folding
- DCE
- inline
- CFG simplify
4. Linker(可选但推荐)
Modules → call graph → DCE → bundle
5. Backend
重点:
- CFG 重建
- 结构化代码
- JIT-friendly 输出
6. runtime(最小化)
只包含:
- helper functions
- minimal polyfill
八、一句话最终结论
所有“编译到 JS”的技术路线,本质是在 IR、runtime、语言约束之间做权衡;如果你的目标是多语言统一编译平台,唯一可扩展的路径是“SSA IR + 可选 Linker + 最小 runtime”,并结合 ReScript 的“JS-friendly 代码生成策略”。
九、如果继续深入
下一步最有价值的不是再看语言,而是:
👉 把你的 IR 写出来
我可以帮你直接落到:
- IR spec(type + instruction)
- 示例 lowering(if / loop / class / closure)
- JS backend mapping
- Linker 设计(call graph + DCE)
这一步会把你从“理解架构”推进到“真正能做系统”。
下面是一份基于你刚才系统性探索的编译到 JavaScript 技术路线深度总结报告。我不会简单罗列,而是帮你把这些语言和架构抽象成几种“根本范式”,并给出工程决策层面的结论。
一、问题本质:编译到 JS 的三种核心矛盾
所有这些语言,本质都在解决三个冲突:
1. 语义 vs JS 表达能力
2. 优化 vs 语义完整
3. 通用性 vs 工程复杂度
二、六大技术路线(统一抽象)
你看到的所有语言,可以压缩成 6种范式:
① 语言收缩型(ReScript / Gleam)
核心思想
Pipeline
特征
优点
缺点
② 语义映射型(Fable / 部分 Nim)
核心思想
Pipeline
特征
优点
缺点
③ IR lowering 型(Kotlin / Scala.js / MoonBit)
核心思想
Pipeline
特征
优点
缺点
④ IR + Linker 型(Scala.js)
核心思想
Pipeline
特征
优点
缺点
⑤ runtime 模拟型(Go / ClojureScript)
核心思想
Pipeline
特征
优点
缺点
⑥ AST 多后端型(Haxe / Nim)
核心思想
Pipeline
特征
优点
缺点
三、统一对比矩阵(核心)
四、关键设计维度(你必须做的选择)
你现在真正要决定的是这几个“轴”:
1. IR 是否是核心?
选 YES(MoonBit / Scala.js)
选 NO(ReScript / Fable)
2. runtime 要多重?
无 runtime(ReScript)
→ 最 JS-native
中 runtime(Kotlin / Fable)
→ 平衡
重 runtime(Go / CLJS)
→ 语义完整
3. 是否做 Linker?
无 linker
→ 小项目 OK
有 linker(Scala.js)
→ 工业级系统
4. 是否支持多语言?
单语言(Kotlin / MoonBit)
→ 更好优化
多语言 IR(你目标)
→ 极高复杂度
五、最重要的工程洞察(精华)
1. IR 的价值不在“翻译”,而在“统一优化空间”
没有 IR:
有 IR:
2. runtime 和 IR 是对冲关系
3. JS backend 的难点不在“生成代码”,而在:
4. “语言设计”比“编译器设计”更重要
ReScript 成功的原因:
5. Linker 是规模化的关键
没有 linker:
6. 大部分系统失败在 runtime
六、你的目标定位(关键判断)
你现在的目标是:
这意味着:
你不能选的路线
❌ ReScript
→ 不支持多语言
❌ Go / CLJS
→ runtime 爆炸
❌ Haxe / Nim
→ 优化不足
你真正的候选路线
方案 A(推荐)
方案 B(进阶)
七、最终架构建议(最重要)
结合所有语言的最佳实践,你的系统应该是:
1. 前端层(多语言)
2. IR 层(核心)
特征:
3. 优化层
4. Linker(可选但推荐)
5. Backend
重点:
6. runtime(最小化)
只包含:
八、一句话最终结论
九、如果继续深入
下一步最有价值的不是再看语言,而是:
👉 把你的 IR 写出来
我可以帮你直接落到:
这一步会把你从“理解架构”推进到“真正能做系统”。