Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/lib/content/using-npm/developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,24 @@ to install it locally into the node_modules folder in that other place.

Then go into the node-repl, and try using require("my-thing") to bring in your module's main module.

#### Catching undeclared ("phantom") dependencies

Under the default hoisted `node_modules` layout, your package can `import` a dependency it never declared and still resolve it.
A transitive dependency hoisted alongside it, or your workspace root's `node_modules`, happens to satisfy the `import`.
That undeclared ("phantom") dependency passes your own build silently, then fails for anyone who installs your package on its own.

We recommend developing your package under [`install-strategy=linked`](/using-npm/config#install-strategy).
The isolated layout only exposes a package's *declared* dependencies, so an `import` of an undeclared package fails for you during development instead of resolving by accident, shipping broken, and failing for your users:

```bash
npm install --install-strategy=linked
npm test
```

> **Note:** This doesn't catch every case.
> A dependency that's still satisfied at your build by a `devDependency` or by your workspace root's `node_modules` can resolve fine for you and still be missing for whoever installs your package.
> So treat it as one check, not a guarantee, alongside auditing the dependencies your published package actually uses.

### Create a User Account

Create a user account on the [npm website](https://www.npmjs.com/signup).
Expand Down
8 changes: 8 additions & 0 deletions tap-snapshots/test/lib/docs.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,14 @@ place, no hoisting. shallow (formerly --global-style) only install direct
deps at top-level. linked: install in node_modules/.store, link in place,
unhoisted.

We recommend that package authors use \`--install-strategy=linked\` during
development to catch undeclared ("phantom") dependencies before publishing:
the isolated layout only exposes a package's declared dependencies, so an
\`import\` of a package that was never added to \`package.json\` can fail
instead of resolving by accident and shipping broken. See [Catching
undeclared ("phantom")
dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies).



#### \`json\`
Expand Down
8 changes: 8 additions & 0 deletions workspaces/config/lib/definitions/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,14 @@ const definitions = {
nested: (formerly --legacy-bundling) install in place, no hoisting.
shallow (formerly --global-style) only install direct deps at top-level.
linked: install in node_modules/.store, link in place, unhoisted.
We recommend that package authors use \`--install-strategy=linked\`
during development to catch undeclared ("phantom") dependencies before
publishing: the isolated layout only exposes a package's declared
dependencies, so an \`import\` of a package that was never added to
\`package.json\` can fail instead of resolving by accident and shipping
broken. See [Catching undeclared ("phantom")
dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies).
`,
flatten,
}),
Expand Down
Loading