cli
cli copied to clipboard
[BUG] .npmignore within subdirectories are ignored when "files" array is used
Is there an existing issue for this?
- [X] I have searched the existing issues
This issue exists in the latest npm version
- [X] I am using the latest npm
Current Behavior
The docs state that when using "files"
in package.json, .npmignore files in subdirectories will override the files inclusions for packaging:
You can also provide a .npmignore file in the root of your package or in subdirectories, which will keep files from being included. At the root of your package it will not override the "files" field, but in subdirectories it will.
https://docs.npmjs.com/cli/v8/configuring-npm/package-json#files
Whatever syntax I try with the subdirectory .npmignore, the files I expect to be excluded are still listed in the package (testing with npm pack --dry-run
).
Expected Behavior
Following the proof of concept below, I would expect the following contents:
npm notice === Tarball Contents ===
npm notice 243B package.json
npm notice 0B src/yes.js
npm notice === Tarball Details ===
Either that, or the docs are wrong or out-of-date.
Have been able to work around by adding a negation pattern to "files" which isn't explicitly documented but seems to work.
Steps To Reproduce
Tested with nodejs 16.10.0 and npm 8.1.4 (MacOS)
mkdir proof-of-concept
cd proof-of-concept
npm init -y
mkdir src
touch src/yes.js src/no.js
echo "no.js" > src/.npmignore
Edit the package.json to include:
"files": ["src/"]
then no.js is still included, despite the .npmignore in the subdirectory:
$ npm pack --dry-run
npm notice
npm notice 📦 [email protected]
npm notice === Tarball Contents ===
npm notice 243B package.json
npm notice 0B src/no.js
npm notice 0B src/yes.js
npm notice === Tarball Details ===
...
Environment
- npm: 8.1.4
- Node: 16.10.0
- OS: MacOS
- platform: it's just on a desk
- npm config:
; "user" config from (omitted)
//registry.npmjs.org/:_authToken = (omitted)
; "env" config from environment
prefix = (omitted)
; node bin location = (omitted)
; cwd = (omitted)
; HOME = (omitted)
I've just tested with:
- npm v7.20.0 — same issue
- npm v6.14.15 — works as expected
so looks like might be a regression that's been kicking around a while.
N.B. There are potential security implications if users are relying on this behaviour to exclude sensitive files from packages.
@robations can you try replicating this problem on the latest version of npm
? (ie. npm i -g npm
)
i tried it there myself and see your expected results. if you're still having this problem, please reopen this issue and let us know.
Sorry @nlf, just saw your reply
I can still reproduce with 8.13.2, but with a slight change to "files"
:
Edit the package.json to include:
"files": ["src/*.js"]
Output
$ npm pack --dry-run
npm notice
npm notice 📦 [email protected]
npm notice === Tarball Contents ===
npm notice 254B package.json
npm notice 0B src/no.js
npm notice 0B src/yes.js
...
So it seems like there is a subtle order of precedence going on here, whereas the docs suggest that .npmignore always takes precedence over files.
Not sure I have permission to reopen, by the way.
More explicitly, can someone reopen this issue?
There's still a bug, or the docs need to be changed to explain better how this works.
this is fixed in npm@9
I just found out that this bug indeed doesn't happen anymore, but only for directories 1 level inside the rootdir, but for 2 levels or more inside the rootdir it still happens!
Environment
- npm: 10.2.5
- Node: 18.2.1
- OS: WSL running in Windows 11 (uname -a:
Linux 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
)
Steps to reproduce
I created the following project structure:
$ tree -a
.
├── .gitignore
├── .npmignore
├── empty.txt
├── folder
│ ├── .gitignore
│ ├── .npmignore
│ ├── empty.txt
│ └── subfolder
│ ├── .gitignore
│ ├── .npmignore
│ └── empty.txt
└── package.json
2 directories, 10 files
All the files above are empty, except for package.json, that has the following content:
{
"name": "npm-pack-gitignore-npmignore",
"version": "1.0.0",
"files": [
"empty.txt",
"folder/empty.txt",
"folder/.gitignore",
"folder/.npmignore",
"folder/subfolder/empty.txt",
"folder/subfolder/.gitignore",
"folder/subfolder/.npmignore"
]
}
When I run npm pack --dry-run
, I get the following output:
npm notice === Tarball Contents ===
npm notice 0B empty.txt
npm notice 0B folder/.gitignore
npm notice 0B folder/.npmignore
npm notice 0B folder/empty.txt
npm notice 0B folder/subfolder/empty.txt
npm notice 279B package.json
Notice that the .gitignore and .npmignore inside the subfolder are not included!
Edit 1
The same happens when I create one more subdir level:
npm notice === Tarball Contents ===
npm notice 0B empty.txt
npm notice 0B folder/.gitignore
npm notice 0B folder/.npmignore
npm notice 0B folder/empty.txt
npm notice 0B folder/subfolder/empty.txt
npm notice 0B folder/subfolder/subsubfolder/empty.txt
npm notice 422B package.json