我一直发布的打包错误(以及我为阻止它们而构建的工具)
Source: Dev.to
出现的问题
1. CJS/ESM 格式不匹配
你的 package.json 写着:
{
"exports": {
"require": "./dist/cjs/index.cjs"
}
}
但 ./dist/cjs/index.cjs 实际上包含 import/export 语句——也就是说它是 ESM。
Webpack 和 esbuild 并不在意,但 Node.js 会因 ERR_REQUIRE_ESM 而崩溃。出现这种情况是因为构建工具在目标为 CJS 时仍输出了 ESM 语法。
2. 条件顺序错误
{
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
}
"types" 应该放在 最前面。TypeScript 按自上而下的顺序解析条件,并在找到第一个匹配项后停止。在这里它先匹配到 "import",于是永远不会看到 "types",导致所有内容都被推断为 any。
3. 子路径缺少声明文件
{
"exports": {
"./utils": "./dist/utils.js",
"./hooks": "./dist/hooks.js"
}
}
如果 dist/utils.d.ts(或 dist/hooks.d.ts)不存在,使用 your-package/utils 的消费者会得到 any 或 “cannot find module”。自己的测试可能因为直接导入源码文件而通过,所以直到有人报告才会发现问题。
这个工具
我编写了 tspub 来捕获这些问题。它会检查约 70 条规则,涵盖 exports、types、文件、元数据、导入以及包体积等方面。
$ npx @tspub-dev/tspub check
exports/format-mismatch ./dist/cjs/index.cjs contains ESM syntax
exports/types-first "types" should be first in conditions
types/no-any-export ./dist/index.d.ts exports 12 `any` types
3 problems (1 auto-fixable)
值得注意的规则
exports/cjs-esmodule-interop– 检测使用__esModule标记的 CJS 文件,这类文件在 Webpack、Node 和 esbuild 中表现不同。types/no-any-export– 标记导出类型中出现过多any的声明文件(通常是构建工具配置错误导致)。exports/format-mismatch– 读取文件内容来验证格式,而不仅仅依据文件扩展名。files/sensitive– 捕获意外包含在发布包中的.env、私钥或凭证等敏感文件。
自动修复
$ npx @tspub-dev/tspub check --fix
该命令会安全地重新排序条件并应用其他简单的修复。
无需安装即可检查任意包
还有网页版可用:tspub.dev/check/YOUR-PACKAGE,可以即时验证任意 npm 包。
超越检查
tspub 还能完成构建、类型声明测试、脚手架新包以及发布等工作。
tspub init # 脚手架一个配置正确的包
tspub build # 生成 ESM + CJS + .d.ts
tspub check # 70 条规则校验
tspub test-types # 类型层面的测试运行器
tspub publish # npm + GitHub 发布
我把它做成一个统一工具,因为在多个包之间分别维护构建、lint、类型测试和发布配置实在难以维系。即使不使用其他功能,单独的检查也能正常工作。
GitHub
npm: npm i -D @tspub-dev/tspub
Web: https://tspub.dev/