Shims 与运行时兼容
为什么需要 shims
库源码可能混用 ESM 和 CJS 的运行时变量:
当源码输出为另一种模块格式时,这些变量可能不存在。Rslib 的 shims 用来弥合部分差异。
默认值
默认 shims:
这个默认值体现了一个判断:CJS 输出兼容 ESM 源码中的 import.meta.* 是常见需求;ESM 输出主动模拟 CJS 全局变量更激进,所以默认关闭。
CJS 中的 import.meta.url
CJS 没有 import.meta.url。Rslib 会通过 EntryChunkPlugin 注入:
这段 shim 同时考虑 Node 和浏览器脚本环境。
为什么注入位置要小心
JS 文件可能以 shebang 开头:
也可能以 strict directive 开头:
shim 插入不能破坏它们。EntryChunkPlugin 会:
- shebang 后插入。
"use strict"后插入。- 其他情况插到文件开头。
这个细节如果处理错,可执行 CLI 或严格模式语义会坏。
ESM 中的 require
如果用户开启:
Rslib 会注入基于 module.createRequire 的 shim:
这让 ESM 产物中可以使用 CommonJS require,但它会引入 Node 运行时假设,因此默认不开。
ESM 中的 **dirname 和 **filename
Rspack 在 output.module = true 时会自动涉及 __dirname、__filename 的处理。Rslib 只有在用户开启对应 shim 时设置 node 选项为 node-module,否则保持 false。
这避免 ESM 产物无意中包含 CJS 兼容层。
disable URL parse
Rslib 还有一个 disableUrlParseRsbuildPlugin,用于阻止 ESM format 中 new URL() 被解析并尝试打包。这个修补来自具体 issue,目的是避免库产物中一些 URL 构造被应用构建式 asset 解析误处理。
它和 import.meta.url shim 都属于 runtime 兼容修补,但关注点不同。
修改风险
Shims 相关改动要检查:
- CJS 输出。
- ESM 输出。
- shebang。
"use strict"。- Node target。
- web target。
- bundleless runtime chunk。
import.meta.urlasset 用法。
这类问题通常表现为运行时错误,不一定构建失败。