要检查共享 npm workspace 软件包实际会交付的内容,请在 monorepo 中运行其测试,对 workspace 打包,然后将该 tarball 安装到 Mac 上的单独临时使用者(consumer)目录中。这样可以捕获 npm 本地 workspace 软链接所隐藏的问题,例如构建文件丢失或软件包入口点不正确。此操作不会向注册表发布任何内容。

1. 从 workspace 根目录运行软件包自有的测试

打开终端并切换到 monorepo 根目录——即包含根 package.json 的目录。确认该软件包出现在根目录的 workspaces 配置中,并且拥有自己的 package.json。npm 会将配置好的 workspace 作为软链接安装在根目录的 node_modules 中,因此在根目录下运行测试可以解析到实时的 workspace 源码。workspace 选项允许你通过声明的名称或目录来定位软件包。npm Workspaces

按 workspace 名称运行软件包的测试脚本,请替换为其 package.json 中的实际名称:

npm run test --workspace=@acme/math

如果该软件包使用了不同的脚本名称,请使用该名称。如果它没有测试脚本,则此命令无法测试其行为;请运行项目实际定义的检查,例如其构建或 lint 脚本。避免仅依赖根级别的测试命令:除非指定了 workspace,否则诸如 test 等 npm 命令均在根目录下执行。npm Workspaces

2. 审查并创建软件包 tarball

本地 workspace 测试并不能证明使用者所需的文件均已包含在软件包中。首先从 monorepo 根目录预览所选 workspace 的软件包内容:

npm pack --workspace=@acme/math --dry-run

查看文件列表,检查软件包入口点、构建输出、类型声明以及软件包承诺提供的任何其他文件。npm 的 files、.npmignore 和 .gitignore 设置会影响打包内容;package.json 以及 README 和许可证文件属于 npm 默认包含的文件。检查 main 或 exports 指向的文件是否存在于归档包中。npm pack、package.json 文件与入口点

当文件列表确认无误后,在临时目录中创建一个真实的 tarball。以下命令使用 macOS 默认兼容 zsh 的引号格式,并将构建产物保留在代码仓库之外:

scratch="$(mktemp -d "${TMPDIR:-/tmp}/workspace-package-check.XXXXXX")"
npm pack --workspace=@acme/math --pack-destination="$scratch"

--dry-run 仅报告 npm 将要打包的内容,并不会生成归档包。第二条命令确实会生成归档包,但不会上传它。npm 文档中说明了 npm pack 会创建一个 tarball,并支持 workspace 选择器。npm pack

3. 在干净的使用者目录中安装归档包

获取 tarball 的路径,创建一个单独的使用者目录,并在其中安装该归档包。本示例假设临时目录中只打包了一个 tarball:

tarball="$(find "$scratch" -maxdepth 1 -name '*.tgz' -print -quit)"
consumer="$scratch/consumer"
mkdir -p "$consumer"
cd "$consumer"
npm init -y
npm install "$tarball"

安装 .tgz 可以对打包后的产物进行测试。直接安装 workspace 文件夹或使用 monorepo 的链接依赖项,其表现可能会有所不同。npm install

现在通过其公共入口点调用该软件包。使用该软件包的真实名称,并根据其 API 编写一个简短的使用者检查脚本——例如,require 或 import 它,然后调用一个有代表性的导出函数。在使用者目录中运行该检查,此时该软件包将从新安装的 node_modules 中解析。如果项目发布编译后的输出,请在打包前验证构建是否已执行;否则即使开发阶段的测试通过,归档包中也可能会缺失文件。

4. 在发布前排查故障

如果安装失败,请检查归档包中是否包含带有 name 和 version 的 package.json,然后检查其文件列表并确认配置的入口点存在于 tarball 中。如果导入失败,请将使用者的模块格式与软件包的 type、main 和 exports 设置进行比对。软件包可能通过了 workspace 测试,但在这里失败,因为这些测试可能会直接加载源文件,或者从 monorepo 中解析出未声明的依赖项。

如果依赖项是另一个未发布的 workspace,请一并测试预期的发布方案。安装单个 tarball 的使用者不会通过 monorepo 链接自动获取同级 workspace 的源码。请确保同级软件包已发布或具有可用的兼容版本,或者采用特意配置的打包(bundled)或可安装方案。该流程仅在当前的 Mac/Node 环境中验证本地打包的软件包;它无法验证其在所有 Node 版本、操作系统或注册表配置下的行为表现。

一个合理的检查终止节点是:workspace 测试通过、软件包文件列表无误,并且在 monorepo 外部成功安装并调用了该 tarball 的使用者检查。如果你需要进一步检查,可以保留该临时目录;或者在确认变量仍指向生成的临时路径后,使用 rm -rf "$scratch" 将其删除。

来源