Midevilworm
Midevilworm

Reputation: 491

Npm install from repo not running `prepare`

I have an npm package for common components hosted on an internal git server. For some reason when I call npm install in another project I want to consume this in it will not run the prepare hook. Obviously, this does not work since the npm package needs a /dist folder in node_modules to be able to consume the package.

I have already tried things such as using the deprecated prepublish hook and even that does not get called. I also tried to do postinstall to see if I could build after install, while that hook did get called it failed because the devDependencies were not installed

package.json

{
  "name": "common-components",
  "version": "0.1.0",
  "scripts": {
    "prepare": "npm run build",
    "build": "ng build",
    ...
  },
  "private": true,
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  },
}

command being used for install

npm install --save git+ssh://{URL-to-common-components-repo}}

I have read through the npm-scripts documentation https://docs.npmjs.com/misc/scripts thoroughly and it seems like they insist that prepare hook should always be called for this exact use-case

Updated 5/6/2019

Just as a note I found this bug on NPM community https://npm.community/t/using-npm-ci-does-not-run-prepare-script-for-git-modules/632/4.

I am using npm 6.4.1 which should work according to the bug

Upvotes: 31

Views: 9078

Answers (6)

Phạm Huy Phát
Phạm Huy Phát

Reputation: 1096

If you are using root user to npm install the package then the prepare script might not be triggered. The reason was the prepare child process has no permission to run (user account was set to default of 'nobody' when using npm with root). You can read more here: https://github.com/npm/npm/issues/17346

To fix this, in the lib package, create an .npmrc file and add:

unsafe-perm: true

Upvotes: 0

Aram Panasenco
Aram Panasenco

Reputation: 108

It's very likely that your dist/ folder is in your .gitignore file. According to this response from an npm-cli maintainer:

In order to be able to properly prepare a git repo npm will run the extracted files through npm-packlist in order to get the expected files that are going to be placed in your node_modules folder.

Further checking the documentation of npm-packlist, we find that npm-packlist will respect the .gitignore file if it has nothing else to go off of:

If there's no package.json with a files list, and there's no .npmignore file, but there is a .gitignore file, then ignore all the files in the .gitignore file.

This article further expands on the idea.

It seems to me that the best fix is to explicitly declare the files that your package needs (including dist/) in the files section of your package.json file. Then you have complete control over what's included and the package size is minimized.

Upvotes: 1

mob
mob

Reputation: 76

If adding an empty .npmignore does not help, you can try specifying all files in dist explicitly in package.json#files. If this works you might want to consider using a wildcard pattern that matches the files in dist to simplify the package.json.

package.json

    ...
    "files": [
        "source",
        "dist/cjs/main.js",
        "dist/es/main.js"
    ]
}

see this comment to a similar issue in the npm/cli repository https://github.com/npm/cli/issues/1287#issuecomment-635021757

Upvotes: 4

maxcc00
maxcc00

Reputation: 345

Adding main in the package.json fixed this issue for me.

    "main": "./dist/index.js",
    "scripts": {
       "build": "babel src --out-dir dist",
       "prepare": "npm run build",
       "lint": "eslint ."
     },

node v14.15.4 npm 6.14.11

Upvotes: -1

FiveOFive
FiveOFive

Reputation: 441

One thing to check that hit me on a package recently - if there is a .gitignore and not .npmignore npm may be ignoring your /dist folder. Adding an empty .npmignore worked in this case.

"If there’s no .npmignore file, but there is a .gitignore file, then npm will ignore the stuff matched by the .gitignore file. If you want to include something that is excluded by your .gitignore file, you can create an empty .npmignore file to override it."

from https://docs.npmjs.com/misc/developers

Upvotes: 15

Midevilworm
Midevilworm

Reputation: 491

For those that are wondering the status of this. I was unable to ever get it to work. What I ended up doing was hosting the components on a private npm registry and that works fine since the npm publish command will do the build and only publish the dist folder

Upvotes: 8

Related Questions