【问题标题】:How to test an `npm publish` result, without actually publishing to NPM?如何在不实际发布到 NPM 的情况下测试“npm 发布”结果?
【发布时间】:2018-10-16 19:38:46
【问题描述】:

我遇到的一个常见问题是,有时我的 .npmignore 文件过于激进,我忽略了我实际上将包含在 NPM tarball 中的文件。

我的问题是 - 有没有办法测试 NPM 发布的结果,而不实际发布到 NPM?

我在想这样的事情。假设我有一个包名为“foo”的本地 NPM 包

set -e;
local proj="bar";
local path_to_foo="."
mkdir -p "$HOME/.local.npm"
npm --tarball -o "$HOME/.local.npm"  # made up command, but you get the idea
(
  cd "$HOME/.temp_projects"
  rm -rf "$proj"
  mkdir "$proj"
  cd "$proj"
  npm init -f
  npm install "$path_to_foo"
)
copy_test_stuff -o "$HOME/.temp_projects/bar"

cd "$HOME/.temp_projects/bar"
npm test

我认为这行不通。因为我们在 NPM 发布压缩包中包含的任何内容都可能不足以进行完整测试。但是,如果我们在执行copy_test_stuff 时复制所有测试文件(包括夹具等),它可能会起作用吗?

【问题讨论】:

  • 这是 2012 年的,但有一些信息:podefr.tumblr.com/post/30488475488/…
  • 与其做一个单一的 npm 包,我会做 Facebook 在 create-react-app github.com/facebook/create-react-app/pull/3744 上所做的事情。他们将注册表模拟为 verdaccio,发布和测试其他依赖项。这是一种可靠的方法,因为您可以轻松测试整个工作流程。 Babel.js、pnpm 和 mozilla neutrino 也是如此。我认为这是处理这个问题的聪明方法。
  • @JuanPicado 很酷,如果您可以将其添加为答案而不是评论,可能会得到一些支持

标签: node.js npm


【解决方案1】:

我会详细说明我之前发布的评论(感谢 Alexander Mills)。

我是verdaccio 的贡献者,因此,我密切关注谁在实施以及如何实施 verdaccio。我将描述我发现并且可能很有趣或作为有效答案的夫妻或示例(主要是 e2e)。

创建反应应用程序

到目前为止,最流行的集成。让我给你一些背景信息,他们正在使用lerna,并且有多个包需要在发布到主注册表之前进行测试(npmjs)。我会 quote here Dan Abramov 解释他们使用自定义注册表的原因。

script is self-explanatory 但让我强调一些部分。

+nohup npx verdaccio@2.7.2 &>$tmp_registry_log &
+# Wait for `verdaccio` to boot
+grep -q 'http address' <(tail -f $tmp_registry_log)
+
+# Set registry to local registry
+npm set registry http://localhost:4873
+yarn config set registry http://localhost:4873
+
+# Login so we can publish packages
+npx npm-cli-login@0.0.10 -u user -p password -e user@example.com -r http://localhost:4873 --quotes

 # Test local start command
 yarn start --smoke-test

+./tasks/release.sh --yes --force-publish=* --skip-git --cd-version=prerelease --exact --npm-tag=latest

如您所见,他们正在运行verdaccio,而不是他们决定使用npm-cli-login 的自定义配置文件,然后他们针对verdaccio 运行测试。一切准备就绪后,他们会在 verdaccio 上发布。作为最后一步,稍后在同一个文件中,他们使用自己的应用程序获取包。

pnpm

他们创建了一个名为 pnpm-registry-mock 的项目,这是一个抽象,允许他们在运行测试之前运行 verdaccio。

 "pretest:e2e": "rimraf ../.tmp/ && rimraf node_modules/.bin/pnpm && pnpm-registry-mock prepare",
 "test:e2e": "preview --skip-prepublishOnly && npm-run-all -p -r pnpm-registry-mock test:tap",
 "test": "npm run lint && npm run tsc && npm run test:e2e", 

基本上,他们使用 npm 脚本准备 verdaccio 并在最后一步运行测试。我不能说太多细节,因为我看到的只是肤浅的。但我知道它的作用。

Mozilla 中微子

我是work in progress,但是,在这里提一下也很有趣。

+if [ "$PROJECT" == "all" ]; then
+  yarn link:all;
+  yarn validate:eslintrc;
+  yarn lint;
+  yarn build;
+  yarn test;
+else
+  yarn verdaccio --config verdaccio.yml & sleep 10;
+  yarn config set registry "http://localhost:4873";
+  npm config set registry "http://localhost:4873";
+  .scripts/npm-adduser.js;
+  yarn lerna publish \
+    --force-publish=* \
+    --skip-git \
+    --skip-npm \
+    --registry http://localhost:4873/ \
+    --yes \
+    --repo-version $(node_modules/.bin/semver -i patch $(npm view neutrino version));
+  yarn lerna exec npm publish --registry http://localhost:4873/;
+  PROJECT="$PROJECT" TEST_RUNNER="$TEST_RUNNER" LINTER="$LINTER" yarn test:create-project;
+fi

同样的方法,正在构建项目,然后正在执行 verdaccio 并发布所有包。

Babel.js

我知道 Babel.js 一直在对 Babel 6 进行冒烟测试,并且拥有 plans to integrate a registry with Babel 7。我quote Henry Zhu early this year talking about babel-smoke-testscreate-react-app 的同一线程中。

实验名为babel-smoke-testsbabel-smoke-tests/scripts/test.sh 是您的密钥文件。

在这里,我看到了与其他项目相同的模式。他们正在启动verdaccio,然后他们会做他们的事情。

START=$(cd scripts; pwd)/section-start.sh
END=$(cd scripts; pwd)/section-end.sh

$START 'Setting up local npm registry' setup.npm.registry
node_modules/.bin/verdaccio -l localhost:4873 -c verdaccio.yml &

export NPM_CONFIG_REGISTRY=http://localhost:4873/

NPM_LOGIN=$(pwd)/scripts/npm-login.sh

$NPM_LOGIN

$END 'Done setting up local npm registry' setup.npm.registry

scripts/bootstrap.sh

export THEM=$(cd them; pwd)

if [[ $SPECIFIC_TEST ]]; then
    scripts/tests/$SPECIFIC_TEST.sh
else
    scripts/tests/jquery.sh
    scripts/tests/react.sh
fi

总结

首先,我希望我的小型研究能够为您提供解决问题的新思路。我认为npm pack 解决了一些问题,但是使用verdaccio 模拟注册表,这对您来说非常轻巧且易于使用,这可能是一个真正的选择。一些大型项目正在(或开始)使用它,它们或多或少遵循相同的方法。那么,为什么不试试呢? :)

https://www.verdaccio.org/

【讨论】:

  • 当然 verdaccio 听起来很酷,虽然我认为 npm pack 应该就足够了,模拟注册表可能更难,容易出错,等等。
  • npm pack 确实有效地探测了 tarball 的内容,但是您无法证明解析依赖项和传递依赖项是否正常工作。这是我为此目的所做的演示(与我的回答有关)docs.google.com/presentation/d/…
  • 使用 verdaccio 和 npmrc,您可以发布一堆相互依赖的包(到本地主机)并使用 npm install 确保他们的部门工作。 verdaccio 有很多 deps,所以我全局安装了npmrcmkdir ~/.npmrcs/verdaccio-server &amp;&amp; (cd $_ &amp;&amp; npm init -y &amp;&amp; npm install --save verdaccio) 有一个服务器,我可以在更改到测试配置文件时启动它(npmrc test);很容易找到但有点混乱,因为 npmrc 将 verdaccio-server 列为 npm 配置文件。 rm -r .local/share/verdaccio/storage/&lt;your packages&gt; 测试后清理。
【解决方案2】:

我遇到了完全相同的问题,因此我创建了一个名为 package-preview 的包。 package-preview 的作用是:

  1. 打包你的包(这是 npm 在发布之前所做的)
  2. 在临时位置安装您的软件包
  3. 将包链接到项目的 node_modules

这使您基本上可以在测试中将包作为依赖项。所以在“awesome-pkg”的测试中,而不是require('../lib') 你写require('awesome-pkg')

我在所有 pnpm 存储库中都使用了这个包几个月,它运行得非常好。我还发布了一篇关于这个包的文章,解释了它可以捕获的所有不同错误:Never ever forget to install a dependency

【讨论】:

  • 很好,这基本上就是我对r2g 所做的,除了我没有链接 node_modules 文件夹。部分目的是测试安装后/预安装例程,所以你在欺骗你的人! :) 我希望我正在测试的任何包都能从main 导出一个名为 r2gSmokeTest 的函数,这个函数冒烟测试他们的包,他们必须实现它。
  • 再次阅读后,这是一个非常好的解决方案。但是主要测试必须写在require('x')而不是require('../../x')
【解决方案3】:

我看到太多复杂的答案,但是根据文档,您只需要全局安装本地包(因为它将安装在不同的目录中)

转到您的模块根目录并执行

npm install . -g

【讨论】:

  • 这行得通,但没有考虑在package.json 中使用files 关键字实现的白名单
【解决方案4】:

(2019 年答案)

简单运行

npm pack

npm 6 及更高版本中,这将显示要上传的文件并在当前目录中创建一个 tar 球。

【讨论】:

  • 我们还可以使用npm publish --dry-run 来准确找出包含哪些文件,而无需生成压缩包。
【解决方案5】:

参考 npm 文档:

[--dry-run] 从 npm@6 开始,除了 实际发布到注册表。报告内容的详细信息 已发布。

类似于 --dry-run 参见 npm pack,它计算出要包含的文件并将它们打包成一个 tarball 以上传到注册表。

https://docs.npmjs.com/cli/v6/commands/npm-publish#description

【讨论】:

    猜你喜欢
    • 2021-08-23
    • 2021-12-24
    • 1970-01-01
    • 2015-10-25
    • 2018-09-26
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多