Npm postinstall only on development

2019-02-02 03:56发布

I have npm module with following package.json

{
  "name": "my-app",
  "version": "0.0.0",
  "scripts": {
    "prepublish": "bower install",
    "build": "gulp"
  },
  "dependencies": {
    "express": "~4.0.0",
    "body-parser": "~1.0.1"
  },
  "devDependencies": {
   "gulp": "~3.6.0",
   "bower": "~1.3.2"
  }
}

When I deploy my app to production I don't want install devDependecies so, I run npm install --production. But in this case prepublish script are called, but it doesn't need, because I use CDN links in production.

How to call postinstall script only after npm install but not after npm install --production?

8条回答
Melony?
2楼-- · 2019-02-02 04:02

I think you cannot choose what scripts are run based on the --production argument. What you can do, however, is supply a script which tests the NODE_ENV variable and only runs bower install if it's not "production".

If you are always in a unix-y environment, you can do it like this:

{ 
  scripts: {
    "prepublish": "[ \"$NODE_ENV\" != production ] && bower install"
  }
}
查看更多
聊天终结者
3楼-- · 2019-02-02 04:02

I'm using if-env module. It's less verbose.

PS: I didn't test it on windows yet.

Install with:

npm i if-env

than in package.json scripts:

"postinstall-production": "echo \"production, skipping...\"",
"postinstall-dev": "echo \"doing dev exclusive stuff\"",
"postinstall": "if-env NODE_ENV=production && npm run postinstall-production || npm run postinstall-dev"
查看更多
forever°为你锁心
4楼-- · 2019-02-02 04:07

I have a more general problem - where I want to skip running the postinstall script on local (direct) installs - like when I'm developing the package and run yarn add --dev my-new-dependency.

This is what I came up with. It works with both npm and yarn.

postinstall.js:

const env = process.env;
if (
    // if INIT_CWD (yarn/npm install invocation path) and PWD
    // are the same, then local (dev) install/add is taking place
    env.INIT_CWD === env.PWD ||
    // local (dev) yarn install may have been run
    // from a project subfolder
    env.INIT_CWD.indexOf(env.PWD) === 0
) {
    console.info('Skipping `postinstall` script on local installs');
}
else {
    // do post-installation things
    // ...
}

package.json:

"script": {
    "postinstall": "node postinstall.js",
    ...
查看更多
爷、活的狠高调
5楼-- · 2019-02-02 04:11

This only works if you're on a unix-like environment:

NPM sets an environment variable to "true" when install is run with --production. To only run the postinstall script if npm install was not run with --production, use the following code.

"postinstall": "if [ -z \"$npm_config_production\" ]; then node_modules/gulp/bin/gulp.js first-run; fi",
查看更多
霸刀☆藐视天下
6楼-- · 2019-02-02 04:20

Solution that is less dependent on unix nature of your shell:

  "scripts": {
    "postinstall": "node -e \"process.env.NODE_ENV != 'production' && process.exit(1)\" || echo do dev stuff"
  },
查看更多
不美不萌又怎样
7楼-- · 2019-02-02 04:27

Newer npm (& Yarn) versions include support for the prepare script that is run after each install run but only in development mode. Also, the prepublish is deprecated. This should be enough:

{
  scripts: {
    "prepare": "bower install"
  }
}

Docs: https://docs.npmjs.com/misc/scripts

查看更多
登录 后发表回答