文档 / 语言手册 / 与 JS 的构建系统交互
Edit

与 JS 的构建系统交互

如果你从 JS 世界来,很有可能你现有的项目已经有一套构建系统。如果你想引入一些 ReScript 代码,下面就将概述 rescript 会在构建管线里扮演什么样的角色。

尽量不要将 rescript 封装进你自己的增量构建框架。要弄清楚 ReScript 的编译过程很难。如果你非要在其之上封装一层,那么,你要么会得到过期的构建物,要么会发现构建过程性能不佳(因此不符合我们的价值主张)。

流行的 JS 构建系统

JS 生态使用 browserifyrollupwebpack 诸如此类的构建系统,最后那个可能是三者中最流行的(至少在 2019 年是这样的 =P)。这些构建系统既负责编译又负责链接(也就是把多个文件打包为一个或几个文件)。

rescript只负责编译;它将 .res.resi 文件映射为 JS 输出文件。因此,从理论上讲,我们这边不需要集成构建系统。站在 webpack 的监听器的角度,ReScript 生成的 JS 文件几乎等同于你手写的 JS 文件。我们还建议首先检查那些 ReScript 生成的 JS 文件,因为这种工作流程意味着:

  • 你可以在不影响现有的基础架构下,将 ReScript 无声无息地引入你的代码库中。

  • 当你更新 .res 文件并改变 JS 构建产物时,你会对 JS 文件的性能和正确性有一种视觉感受上的不同。

  • 紧急情况下,你可以让团队成员对 JS 文件进行热修复,而不需要先开始学习 ReScript。

  • 你可以从你的代码库中完全删除 ReScript,而代码还能继续跑(以防你的公司因任何原因决定停止使用我们)。

值得一提的是,你也可以把 rescript 变成构建管线的一个自动化步骤,比如 webpack 加载器。但这种方法容易出错,因此不提倡。

技巧和诀窍

你可以在 bsconfig.json 中配置 in-sourcesuffix 字段,使 ReScript JS 看上去更地道:

JSON
{ "package-specs": { "module": "commonjs", // or whatever module system your project uses "in-source": true }, "suffix": ".bs.js" }

这会:

  • 与 ReScript 源文件一起生成 JS 文件

  • 使用文件扩展名 .bs.js,这样就可以通过 require('./MyFile.bs') 在 JS 中导入这些文件,而不需要用到加载器

在 ReScript 端使用加载器

“如果我的构建系统使用了 CSS/png 等其他加载器,而我想在 ReScript 中使用它,怎么办?”

加载器确实很麻烦;同时,请在文件顶部使用如 %raw("require('./myStyles.css')") 这样的命令。这会使 raw 将代码片段编译成一个实际的 JS require。

获取项目的依赖关系

rescript 为每个 MyFile 源文件生成一个 MyFile.d 文件;你可以在 lib/bs 中找到它们。文件内容是人类可读,同时也对机器友好的 MyFile 依赖列表。你可以按你所想读取这些文件(但要注意 IO 的开销)。请使用这些文件而不要自己创建依赖关系图;我们做了艰苦的工作来尽可能地跟踪这些依赖关系(包括内部模块、open、模块名称重叠等等)。

构建后运行脚本

请参考 js-post-build。不过请谨慎使用;如果在每个文件构建后都挂上一个 node.js 脚本,那么每多一个文件,就会增加一点 node 的启动时间。