Npm仅在开发时安装后

时间:2014-04-15 07:17:53

标签: javascript node.js continuous-integration npm

我的npm模块包含以下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"
  }
}

当我将我的应用部署到生产环境时,我不想安装devDependecies,因此我运行npm install --production。但在这种情况下,prepublish脚本被调用,但它并不需要,因为我在生产中使用CDN链接。

如何仅在npm install之后而不是npm install --production之后调用postinstall脚本?

8 个答案:

答案 0 :(得分:17)

我认为您无法根据--production参数选择运行的脚本。但是,你可以做的是提供一个测试NODE_ENV变量的脚本,如果它不是"生产"则只运行bower install

如果你总是在unix-y环境中,你可以这样做:

{ 
  scripts: {
    "prepublish": "[ \"$NODE_ENV\" != production ] && bower install"
  }
}

答案 1 :(得分:14)

这仅适用于类似unix的环境:

NPM将环境变量设置为" true"使用--production运行安装时。要仅在未使用--production运行npm install时运行postinstall脚本,请使用以下代码。

"postinstall": "if [ -z \"$npm_config_production\" ]; then node_modules/gulp/bin/gulp.js first-run; fi",

答案 2 :(得分:11)

较新的npm(& Yarn)版本包括对每个prepare运行后运行但仅在开发模式下运行的install脚本的支持。此外,不推荐使用prepublish。这应该足够了:

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

文档:https://docs.npmjs.com/misc/scripts

答案 3 :(得分:10)

我使用windows,osx和linux,所以我使用非特定于环境的解决方案来解决这个问题:

postinstall 处理程序中,我执行一个js脚本来检查process.env.NODE_ENV变量并完成工作。

在我的具体情况下,我必须只在开发环境中执行gulp任务:

package.json的一部分

"scripts": {
  "postinstall": "node postinstall"
}

所有postinstall.js脚本

if (process.env.NODE_ENV === 'development') {
  const gulp = require('./gulpfile');
  gulp.start('taskname');
}

gulpfile.js的最后一行

module.exports = gulp;

从gulpfile.js导出gulp很重要,因为所有任务都在特定的gulp实例中。

答案 4 :(得分:6)

较少依赖shell的unix性质的解决方案:

  "scripts": {
    "postinstall": "node -e \"process.env.NODE_ENV != 'production' && process.exit(1)\" || echo do dev stuff"
  },

答案 5 :(得分:0)

我正在使用if-env模块。它不那么冗长。

PS :我还没在Windows上测试它。

安装时:

npm i if-env

而不是package.json脚本:

"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"

答案 6 :(得分:0)

在这里降落是因为我遇到了同样的问题。最终得到了一个解决方案,该解决方案测试了我知道应该仅在开发中可用的node_modules下是否存在软件包。

{
  "scripts": {
    "postinstall": "bash -c '[ -d ./node_modules/@types ] && lerna run prepare || echo No postinstall without type info'" 
  }
}

从概念上讲,这对我来说很好,因为lerna在这里调用的prepare脚本主要用于ts-to-js编译。

答案 7 :(得分:0)

我有一个更普遍的问题-我想跳过在本地(直接)安装上运行postinstall脚本的情况-就像我在开发软件包并运行yarn add --dev my-new-dependency时一样。

这是我想出的。它适用于npm和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",
    ...