Bundleless outBase 与 entry

outBase 是什么

在 bundleless 模式下,Rslib 会把多个源码文件变成多个 entry。outBase 是这些 entry 的共同基准目录。输出 entry name 会根据文件相对 outBase 的路径生成。

例如:

src/index.ts
src/components/Button.tsx

outBase 是 src 时,entry name 是:

index
components/Button

输出会保留目录结构。

默认 outBase

如果用户不配置 outBase,Rslib 会计算所有非声明输入文件的最长公共路径。这类似 TypeScript rootDir 或 esbuild outbase 的思路。

这样可以在多数项目中自动得到符合预期的结构。

为什么过滤 dts 文件

Bundleless entry 扫描可能匹配到:

src/index.d.ts

声明文件不应该作为 JS entry 编译。Rslib 会过滤 .d.ts.d.mts.d.cts

声明文件生成由 plugin-dts 处理,不由 JS entry 扫描处理。

CSS entry 的特殊标记

全局 CSS 文件也可能是 entry。CSS extract 过程中可能产生对应 JS asset,但全局 CSS entry 最终不应该留下空 JS 文件。

Rslib 对全局 CSS entry name 加前缀:

__rslib_css__/styles/base

后续 pluginLibCss 会删除带这个标记的虚拟 JS asset。

CSS Modules 不走这个删除路径,因为 CSS Modules 的 JS asset 是有意义的,它导出 class name mapping。

duplicate entry warning

如果两个源文件相对 outBase 后得到同一个 entry name,会出现覆盖风险。例如:

src/foo/index.ts
src/foo/index.js

如果输出扩展名相同,entry name 可能冲突。Rslib 会 warning,提示用户重命名文件。

这类问题构建不一定失败,但产物可能丢文件。

动态 entry

Bundleless entry 在 Rspack config 中是一个 async function。这样 watch 或重新构建时可以重新扫描 glob。

第一次扫描用于计算 outBase;后续动态 entry 用于得到最新文件集合。

outBase 影响哪些系统

outBase 不只是 entry 命名:

  • bundleless external 判断请求是否在源码范围内。
  • bundleless external 计算输出相对路径。
  • CSS loader 计算输出。
  • EntryChunkPlugin 注册 watch context dependency。
  • dts 路径语义需要与 JS 输出保持一致。

因此修改 outBase 逻辑会影响多个系统。

用户显式 outBase

用户可以配置:

lib: [
  {
    bundle: false,
    outBase: 'src',
  },
];

显式 outBase 会覆盖最长公共路径推导。它可以解决 monorepo 或多目录 entry 中默认推导不符合预期的问题。

但如果用户设置过窄或过宽,可能导致输出结构异常,或者 bundleless external 判断边界不准确。

测试建议

outBase 相关改动应覆盖:

  • 默认 outBase。
  • 用户显式 outBase。
  • 嵌套目录。
  • 多 glob。
  • CSS entry。
  • duplicate entry。
  • 新增文件 watch。
  • redirect 路径。

相关测试在:

  • tests/integration/outBase
  • tests/integration/entry
  • tests/integration/bundle-false
  • tests/integration/redirect