cli icon indicating copy to clipboard operation
cli copied to clipboard

[BUG] .npmignore within subdirectories are ignored when "files" array is used

Open robations opened this issue 3 years ago • 9 comments

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) 

robations avatar Nov 19 '21 16:11 robations

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.

robations avatar Nov 19 '21 16:11 robations

N.B. There are potential security implications if users are relying on this behaviour to exclude sensitive files from packages.

robations avatar Nov 19 '21 16:11 robations

@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.

nlf avatar May 31 '22 17:05 nlf

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.

robations avatar Jul 06 '22 15:07 robations

Not sure I have permission to reopen, by the way.

robations avatar Jul 06 '22 15:07 robations

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.

robations avatar Jul 21 '22 10:07 robations

this is fixed in npm@9

nlf avatar Dec 13 '22 21:12 nlf

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

pgcalixto avatar Dec 15 '23 23:12 pgcalixto