How to test an `npm publish` result, without actually publishing to NPM?

node.jsNpm

node.js Problem Overview


One common problem I have, is that sometimes my .npmignore file is too aggressive, and I ignore files that I actually will to include in the NPM tarball.

My question is - is there a way to test the results of NPM publish, without actually publishing to NPM?

I am thinking something like this. Assuming I have a local NPM package with package name "foo"

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

I don't think this will work. Because whatever we include in the NPM publish tarball, might not have enough to do the full test. But maybe if we copy all the test files (including fixtures, etc) when we do copy_test_stuff, it might work?

node.js Solutions


Solution 1 - node.js

(2019 answer)

Simply run

npm pack

In npm 6 and up, this will display what files are going to be uploaded and create a tar ball in the current directory.

Solution 2 - node.js

I'll elaborate my comment I posted earler, (thanks Alexander Mills).

I'm a verdaccio contributor, so, I closely follow whom are implementing and how to verdaccio. I'll describe couples or examples (e2e mostly) that I've found and might be interesting or as a valid answer.

create-react-app

By far, the most popular integration. Let me give you some context, they are using lerna and have multiple packages that need to test before to publish on main registry aka (npmjs). I'll quote here Dan Abramov explaining their reasons to use a custon registry.

The script is self-explanatory but let me highlight some parts.

+nohup npx [email protected] &>$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 [email protected] -u user -p password -e [email protected] -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

As you see, they are running verdaccio and instead a custom config file they have decided to use npm-cli-login and then they run the tests against verdaccio. When all is ready, they publish on verdaccio. As last step, later in the same file, they fetch packages with their own app.

pnpm

They have created a project called pnpm-registry-mock which is an abstraction that allows them to run verdaccio before running the tests.

 "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", 

Basically, using npm scripts they prepare verdaccio and run the test as last step. I cannot go too much into details, since I've only saw it shallowly. But I know what it does.

Mozilla Neutrino

This is work in progress, but, it's also interesting to mention here.

+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

Again, the same approach, project is being built and then verdaccio is being executed and they publish all packages.

Babel.js

I know Babel.js has been experimenting with a smoke-testing for Babel 6 and have plans to integrate a registry with Babel 7. I quote Henry Zhu early this year talking about babel-smoke-tests in the same thread of create-react-app.

The experiment is called babel-smoke-tests and babel-smoke-tests/scripts/test.sh is the key file for you.

Here I see the same pattern than other projects. They are launching verdaccio and then they do their stuff.

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

Wrap up

First of all, I hope my small research give you new ideas how to address your issue. I think npm pack solve some issues, but mocking a registry using verdaccio which is quite light and straightforward to use might be a real option for you. Some big projects are being (or getting started) using it and they follow more or less the same approach. So, Why don't try? :)

https://www.verdaccio.org/

Solution 3 - node.js

I had the exact same problem, so I created a package called package-preview. What package-preview does is:

  1. packs your package (it is what npm does before publish)
  2. installs your package in a temp location
  3. links the package to your project's node_modules

This allows you to basically require the package as a dependency in your tests. So in tests of "awesome-pkg", intead of require('../lib') you write require('awesome-pkg')

I use this package in all the pnpm repos for several months and it works really well. I also posted an article about this package that explains all the different errors that it can catch: Never ever forget to install a dependency

Solution 4 - node.js

I see too many complicated answers, but according to documentation, you just need to install your local package globally (because it will be installed on different directory)

Go to your module root directory and do

npm install . -g

Solution 5 - node.js

Referring to npm docs:

> [--dry-run] As of npm@6, does everything publish would do except > actually publishing to the registry. Reports the details of what would > have been published.

> Similar to --dry-run see npm pack, which figures out the files to be included and packs them into a tarball to be uploaded to the registry.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser7898461View Question on Stackoverflow
Solution 1 - node.jsBen WindingView Answer on Stackoverflow
Solution 2 - node.jsJuan PicadoView Answer on Stackoverflow
Solution 3 - node.jsZoltan KochanView Answer on Stackoverflow
Solution 4 - node.jsJoão Pimentel FerreiraView Answer on Stackoverflow
Solution 5 - node.jsOzan MudulView Answer on Stackoverflow