构建系统配置
bsconfig.json
是 rescript
强制需要的唯一的构建元数据文件。
完整的构建配置概要在这里。接下来我们将简要介绍构建配置中的重要部分。
name 和 namespace
name
是指的库的名称,作为库的“命名空间”使用。你可以通过 bsconfig.json
中的 "namespace": true
来激活命名空间。使用命名空间几乎是强制性的,但是我们为了确保向后兼容而没有默认开启。
解释:默认情况下,你的文件一旦被用作第三方依赖,对用户来说在全局作用域上可用。例如,如果你有一个 Util.res
,而你的库的使用者也有一个同名的文件,它们会发生冲突。开启 namespace
可以避免这种情况,命名空间为你项目的所有文件提供一个额外的模块包装层;而不是一个全局的 Util
模块,用户将看到的是 MyProject.Util
。命名空间影响的是你的用户,而不是你自己。
也就是说,在 ReScript 中,“命名空间”只是一个花哨的术语,它指的是自动生成一个模块来包装项目中的所有文件(当然是又快又好的!)供第三方使用。
我们不为你的项目创建文件夹级别的命名空间;你的所有文件名必须是唯一的。这是一个约束条件,基于它可以实现一些特性,如快速搜索和更轻松的项目重组。
注意:bsconfig.json
的 name
应与 package.json
的 name
相同,以避免出现混乱的边界情况。这就意味着你不能使用驼峰命名的名字,如 MyProject
,因为 package.json
和 npm 禁止你这样做(因为有些文件系统不区分大小写)。要想让命名空间/模块的名字是 MyProject
,可以写上 "name": "my-project"
。ReScript 会正确地将它转化为驼峰命名。
关于自定义命名空间的注意事项:如果由于某些原因,你需要与 name
不同的命名空间,你可以给 namespace
选项传递一个字符串。例如,如果你的包是一个名为 bs-some-thing
的绑定,你可以使用 "namespace": "some-thing"
来获得 SomeThing
的命名空间,而不是 BsSomeThing
。
sources
你需要明确指定你的源文件目录(我们不想意外跑到不相关的目录)。例如:
JSON{
"sources": ["src", "examples"]
}
JSON{
"sources": {
"dir": "src",
"subdirs": ["page"]
}
}
JSON{
"sources": [
"examples",
{
"dir": "src",
"subdirs": true // 递归构建所有子目录
}
]
}
你可以把你的目录标记为仅用于开发(dev-only),例如测试目录。这些文件不会被构建然后暴露给第三方,甚至不会暴露给同一项目中的其他“开发”目录。
JSON{
"sources" : {
"dir" : "test",
"type" : "dev"
}
}
bs-dependencies 和 bs-dev-dependencies
ReScript 的依赖项列表,就像 package.json
中的依赖项一样,ReScript 将在 node_modules
中搜索它们。
注意,只有标有 "type":"dev"
的源代码才能够解析 bs-dev-dependencies
中的模块。
pinned-dependencies
自 8.4 版本起可用,固定依赖的列表。每当你用 rescript
构建一个顶层的包(例如你的主程序)时,固定依赖总会被重新构建。
这对于同时处理多个独立的 ReScript 包非常有用。更多使用细节参见固定依赖页面。
external-stdlib
自 9.0 版本起可用,此设置允许依赖外部构建的 stdlib 包(而不是本地构建的 stdlib 运行时)。对于只在 JS 或 TS 中使用而不依赖于 ReScript 开发工具链的包非常有用。
更多细节参见外部标准库页面。
reason 和 refmt (旧)
reason
配置项是默认启用的。要为 ReasonReact 打开 JSX,请指定:
JSON{
"reason": {"react-jsx": 3},
"refmt": 3
}
refmt
配置项应明确指定为 3
。
js-post-build
该选项指定文件重新编译时调用的钩子。有助于和 JS 构建系统互操作,但请谨慎使用。为每个重新编译的文件调用自定义命令会降低构建速度,甚至恶化第三方用户的构建体验。
例子:
JSON{
"js-post-build": {
"cmd": "/path/to/node ../../postProcessTheFile.js"
}
}
注意,命令(本例中为 node
)的路径解析是这样做的:
/myCommand
被解析为/myCommand
package/myCommand
被解析为node_modules/package/myCommand
./myCommand
被解析为myProjectRoot/myCommand
myCommand
只是作为myCommand
被调用,也就是一个全局可用的可执行文件。但要注意的是,ReScript 并不读取你的 shell 环境,所以如果你输入node
,需要指定一个绝对路径,否则 ReScript 无法找到它。你也可以在脚本顶部添加#!/usr/local/bin/node
来直接调用它,而不需要在前面加上node
。
该命令本身是在 lib/bs
中调用的。
package-specs
输出到 CommonJS(默认)或 ES6 模块。例如:
JSON{
"package-specs": {
"module": "commonjs",
"in-source": true
}
}
"module": "es6-global"
使用相对路径解析node_modules
。这有利于 ES6 在开发阶段的使用,并与 Safari 和 Firefox 等支持 ES6 模块的浏览器相结合。不要再在开发时打包了!"in-source": true
表示 JS 输出生成到源文件目录。如果你忽略它,构建生成的制品会放到lib/js
中。没有其他的输出目录可配置。
只有你在开发项目时,这个配置才对你适用。当项目被用作第三方库时,用户自己的 bsconfig.json
package-specs
会覆盖这里的配置。
suffix
后缀可以是 ".js"
,".mjs"
,".cjs "
或 ".bs.js"
。目前倾向于 bs.js
。
设计决策
生成带有 .bs.js
后缀的 JS 文件意味着,在 JS 端你可以这样导入:const myReScriptFile = require('./theFile.bs')
。这样做的好处是:
我们能立刻看出导入的 JS 文件是 ReScript 生成的。
它避免了与同一文件夹中潜在的
theFile.js
文件发生冲突。它避免了为 ReScript 文件使用构建系统加载器。这种方式加上
in-source
进行构建意味着,在基本不修改 JS 构建管线的情况下,就能将 ReScript 项目集成到你的纯 JS 代码库中。genType 要求编译的 JS 制品以
bs.js
为后缀。如果你正在使用genType
,你需要暂时使用bs.js
。
warnings
可选地打开/关闭特定的警告,或把警告变成硬错误(hard error)。例如:
JSON{
"warnings": {
"number": "-44-102",
"error": "+5"
}
}
关闭警告 44
和 102
(多态比较),将警告 5
(部分应用的结果具有函数类型并被忽略)变成硬性错误。
当警告被触发时,警告编号会显示在构建输出中。完整的列表参见警告编号。
bsc-flags
传递给编译器的额外选项,属于进阶用法。
环境变量
我们非常不推荐使用环境变量,但在某些情况下使用它们是合理的。
带颜色的错误输出:NINJA_ANSI_FORCED
这个选项主要是针对不需要输出颜色的 rescript
的其他程序化的用法。
当 NINJA_ANSI_FORCED
被设置为 1
时:rescript
输出会有颜色。
当 NINJA_ANSI_FORCED
被设置为 0
时:rescript
输出不会有颜色。
当 NINJA_ANSI_FORCED
未被设置时。rescript
智能检测它输出到的位置,来确定是否输出颜色。
请注意,底层编译器将始终传递
-color always
。更多细节参见这个 issue。