Visitar URL original
pnpm 12 `pack` / `publish` ignores a nested `.npmignore` when `files` is set (regression from pnpm 11, differs from npm) · Issue #16909 · pnpm/pnpm · GitHub
Skip to content

pnpm 12 pack / publish ignores a nested .npmignore when files is set (regression from pnpm 11, differs from npm) #16909

Closed

Description

@everett1992

Verify latest release

  • I verified that the issue exists in the latest pnpm release (12.12.1; also checked 12.0.0 and every 12.x minor)

pnpm version

12.0.0 through 12.12.1. pnpm 11.0.0, 11.28.5 and 10.34.7 match npm.

Which area(s) of pnpm are affected? (leave empty if unsure)

CLI (pnpm pack / pnpm publish)

Reproduction steps

mkdir -p repro-pkg/src/util && cd repro-pkg
echo '{"name":"repro-pkg","version":"1.0.0","files":["src"]}' > package.json
echo x > src/index.js; echo t > src/index.test.js
echo f > src/util/format.js; echo t > src/util/format.test.js
echo '*.test.js' > src/.npmignore
pnx npm@latest pack --dry-run      # no *.test.js
pnx pnpm@11 pack --dry-run         # no *.test.js
pnx pnpm@12.12.1 pack --dry-run    # packs src/index.test.js and src/util/format.test.js

Describe the Bug

With a files allowlist, pnpm 12 skips every .npmignore / .gitignore, including ones inside the listed directories. npm and pnpm 11 skip only the root ones and keep honoring nested ones within their subtree.

files: ["src"], src/.npmignore = *.test.js:

path npm 12.2.0 pnpm 11.0.0 pnpm 11.28.5 pnpm 12.0.0 pnpm 12.12.1
package.json x x x x x
src/.npmignore - - - x -
src/index.js x x x x x
src/index.test.js - - - x x
src/util/format.js x x x x x
src/util/format.test.js - - - x x

(npm 10.9.9 and 11.21.0 give the same list as npm 12.2.0. The packed src/.npmignore in 12.0.0 to 12.11.x was fixed by #16746.)

Same result for a deeper nested ignore file (files: ["src"] + src/sub/.npmignore), a glob entry (files: ["src/**"] + src/.npmignore) and a nested .gitignore in a directory without .npmignore: npm and pnpm 11 apply it, pnpm 12 does not. Without a files field pnpm 12.12.1 honors nested .npmignore files correctly, and a root .npmignore is ignored by all tools when files is set, as documented.

Packages that keep tests, fixtures or other private files out of a listed directory with a nested .npmignore start publishing them with pnpm 12, with no warning.

Expected Behavior

Match npm-packlist and pnpm 11: when files is set, ignore only the root .npmignore / .gitignore, and keep applying .npmignore (or .gitignore when there is no .npmignore) in subdirectories.

Root cause pointer: in pnpm/crates/fs-packlist/src/lib.rs (v12.12.1, lines 200-204) a usable files matcher selects IgnoreFiles::Skip, and in ignore_walk.rs Skip both empties the root rules (line 40) and sets read_ignore_files: false (line 55), so walk_dir never reads a subdirectory's ignore file (line 108). The crate docs (lib.rs lines 10-12) describe this as intended: "a usable files allowlist disables .gitignore and .npmignore". #13005 introduced the "files disables both" tier and noted that "subdirectory behavior is documented as a known divergence"; now that #16761 walks per directory like ignore-walk, Skip could drop only the root (and workspace-inherited) rules and keep reading nested ones.

pnpm 11 used npm-packlist (pnpm11/fs/packlist, npm-packlist 10.0.4), which is why it matches npm.

Related (same fs-packlist area): #16889 ("files": [] packs everything).

Which Node.js version are you using?

v26.10.0

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is? (Include the version if relevant)

x86_64

Activity

  1. github-actions commented on Oct 13, 2026

    @github-actions
    Contributor

    @everett1992, are you planning to open a pull request for this? If so, reply here and a maintainer will assign the issue to you, so nobody else starts on the same fix.

  2. zkochan commented on Oct 14, 2026

    @zkochan
    Member

    Fix is open in #16920 and covers the whole issue.

    With files set, pnpm pack / pnpm publish now skip only the root (and workspace-inherited) ignore files. A subdirectory's .npmignore, or its .gitignore when it has no .npmignore, applies within its subtree again, as in npm and pnpm 11. Your repro, the src/** glob variant and the nested .gitignore variant are all covered by tests.

    One deliberate difference from npm: a file that a files entry names explicitly still ships even if a nested ignore file excludes it, at any depth. npm keeps it only when it sits directly in the ignore file's directory.


    Written by an agent (Claude Code, claude-opus-5-5).

  3. added a commit that references this issue on Oct 14, 2026
    82b8c90
  4. added a commit that references this issue on Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions