使用npm,我们可以使用-g选项全局安装模块。我们如何在包装中做到这一点。json文件吗?

假设这些是我在包中的依赖项。json文件

"dependencies": {
    "mongoose": "1.4.0",
    "node.io" : "0.3.3",
    "jquery"  : "1.5.1",
    "jsdom"   : "0.2.0",
    "cron"    : "0.1.2"
  }

当我运行npm install时,我只需要node。IO将全局安装,其余的其他应安装在本地。有其他选择吗?


所有模块从包。Json被安装到。/node_modules/

我找不到明确的说明,但这是包。json引用NPM。


新提示:您可能不想或不需要这样做。你可能想要做的就是把build/test等类型的命令依赖放在package.json的devDependencies部分。任何时候你使用包中的脚本。json你的devDependencies命令(在node_modules/.bin中)就像它们在你的路径中一样。

例如:

npm i --save-dev mocha # Install test runner locally
npm i --save-dev babel # Install current babel locally

然后在package.json中:

// devDependencies has mocha and babel now

"scripts": {
  "test": "mocha",
  "build": "babel -d lib src",
  "prepublish": "babel -d lib src"
}

然后在命令提示符下运行:

npm run build # finds babel
npm test # finds mocha

npm publish # will run babel first

注意:现在我们已经有了npx,它允许你运行devDependencies命令,而不需要将它们添加到你的脚本部分(如果你想的话)。 例如:

npx webpack

但是如果你真的想要全局安装,你可以在package.json的scripts部分添加一个preinstall:

"scripts": {
  "preinstall": "npm i -g themodule"
}

所以实际上我的npm install再次执行npm install…这很奇怪,但似乎很有效。

注意:如果你正在使用最常见的npm设置,其中全局Node包安装需要sudo,你可能会遇到问题。一种选择是改变你的npm配置,这样就没有必要了:

npm配置~/npm,添加$HOME/npm/bin到$PATH,添加export PATH=$HOME/npm/bin:$PATH到~/.bashrc

另一个更好的选择是使用nvm来管理Node,这样就不会有这个问题了。


由于以下所述的缺点,我建议遵循以下公认的答案:

使用npm install——save-dev [package_name]然后执行脚本: 运行lint 运行构建 $ NPM测试

以下是我最初但不推荐的回答。


而不是使用全局安装,你可以将包添加到你的devDependencies(——save-dev),然后从项目中的任何地方运行二进制文件:

"$(npm bin)/<executable_name>" <arguments>...

在你的情况下:

"$(npm bin)"/node.io --help

这个工程师提供了一个npm-exec别名作为快捷方式。这个工程师使用一个名为env.sh的shell脚本。但我更喜欢直接使用$(npm bin),以避免任何额外的文件或设置。

虽然它会使每个调用更大一点,但它应该可以工作,防止:

与全局包的潜在依赖冲突(@nalply) 对sudo的需求 需要设置一个npm前缀(尽管我还是建议使用一个)

缺点:

$(npm bin)在Windows上不起作用。 在你的开发树中较深的工具不会出现在npm bin文件夹中。(安装npm-run或npm-which来找到它们。)

更好的解决方案似乎是将常见任务(如构建和缩小)放在包的“脚本”部分。json,正如Jason在上面演示的那样。


这有点老了,但我遇到了要求,所以这是我想出的解决方案。

存在的问题:

Our development team maintains many .NET web application products we are migrating to AngularJS/Bootstrap. VS2010 does not lend itself easily to custom build processes and my developers are routinely working on multiple releases of our products. Our VCS is Subversion (I know, I know. I'm trying to move to Git but my pesky marketing staff is so demanding) and a single VS solution will include several separate projects. I needed my staff to have a common method for initializing their development environment without having to install the same Node packages (gulp, bower, etc.) several times on the same machine.

TL; diana:

需要“npm install”来安装全局Node/Bower开发环境以及。net产品所需的所有本地包。 只有在尚未安装全局包时才应安装。 必须自动创建到全局包的本地链接。

解决方案:

我们已经有了一个由所有开发人员和所有产品共享的公共开发框架,所以我创建了一个NodeJS脚本,在需要时安装全局包并创建本地链接。脚本驻留在“....”中\SharedFiles”相对于产品基本文件夹:

/*******************************************************************************
* $Id: npm-setup.js 12785 2016-01-29 16:34:49Z sthames $
* ==============================================================================
* Parameters: 'links' - Create links in local environment, optional.
* 
* <p>NodeJS script to install common development environment packages in global
* environment. <c>packages</c> object contains list of packages to install.</p>
* 
* <p>Including 'links' creates links in local environment to global packages.</p>
* 
* <p><b>npm ls -g --json</b> command is run to provide the current list of 
* global packages for comparison to required packages. Packages are installed 
* only if not installed. If the package is installed but is not the required 
* package version, the existing package is removed and the required package is 
* installed.</p>.
*
* <p>When provided as a "preinstall" script in a "package.json" file, the "npm
* install" command calls this to verify global dependencies are installed.</p>
*******************************************************************************/
var exec = require('child_process').exec;
var fs   = require('fs');
var path = require('path');

/*---------------------------------------------------------------*/
/* List of packages to install and 'from' value to pass to 'npm  */
/* install'. Value must match the 'from' field in 'npm ls -json' */
/* so this script will recognize a package is already installed. */
/*---------------------------------------------------------------*/
var packages = 
  {
  "bower"                      :                      "bower@1.7.2", 
  "event-stream"               :               "event-stream@3.3.2",
  "gulp"                       :                       "gulp@3.9.0",
  "gulp-angular-templatecache" : "gulp-angular-templatecache@1.8.0",
  "gulp-clean"                 :                 "gulp-clean@0.3.1", 
  "gulp-concat"                :                "gulp-concat@2.6.0",
  "gulp-debug"                 :                 "gulp-debug@2.1.2",
  "gulp-filter"                :                "gulp-filter@3.0.1",
  "gulp-grep-contents"         :         "gulp-grep-contents@0.0.1",
  "gulp-if"                    :                    "gulp-if@2.0.0", 
  "gulp-inject"                :                "gulp-inject@3.0.0", 
  "gulp-minify-css"            :            "gulp-minify-css@1.2.3",
  "gulp-minify-html"           :           "gulp-minify-html@1.0.5",
  "gulp-minify-inline"         :         "gulp-minify-inline@0.1.1",
  "gulp-ng-annotate"           :           "gulp-ng-annotate@1.1.0",
  "gulp-processhtml"           :           "gulp-processhtml@1.1.0",
  "gulp-rev"                   :                   "gulp-rev@6.0.1",
  "gulp-rev-replace"           :           "gulp-rev-replace@0.4.3",
  "gulp-uglify"                :                "gulp-uglify@1.5.1",
  "gulp-useref"                :                "gulp-useref@3.0.4",
  "gulp-util"                  :                  "gulp-util@3.0.7",
  "lazypipe"                   :                   "lazypipe@1.0.1",
  "q"                          :                          "q@1.4.1",
  "through2"                   :                   "through2@2.0.0",

  /*---------------------------------------------------------------*/
  /* fork of 0.2.14 allows passing parameters to main-bower-files. */
  /*---------------------------------------------------------------*/
  "bower-main"                 : "git+https://github.com/Pyo25/bower-main.git" 
  }

/*******************************************************************************
* run */
/**
* Executes <c>cmd</c> in the shell and calls <c>cb</c> on success. Error aborts.
* 
* Note: Error code -4082 is EBUSY error which is sometimes thrown by npm for 
* reasons unknown. Possibly this is due to antivirus program scanning the file 
* but it sometimes happens in cases where an antivirus program does not explain 
* it. The error generally will not happen a second time so this method will call 
* itself to try the command again if the EBUSY error occurs.
* 
* @param  cmd  Command to execute.
* @param  cb   Method to call on success. Text returned from stdout is input.
*******************************************************************************/
var run = function(cmd, cb)
  {
  /*---------------------------------------------*/
  /* Increase the maxBuffer to 10MB for commands */
  /* with a lot of output. This is not necessary */
  /* with spawn but it has other issues.         */
  /*---------------------------------------------*/
  exec(cmd, { maxBuffer: 1000*1024 }, function(err, stdout)
    {
    if      (!err)                   cb(stdout);
    else if (err.code | 0 == -4082) run(cmd, cb);
    else throw err;
    });
  };

/*******************************************************************************
* runCommand */
/**
* Logs the command and calls <c>run</c>.
*******************************************************************************/
var runCommand = function(cmd, cb)
  {
  console.log(cmd);
  run(cmd, cb);
  }

/*******************************************************************************
* Main line
*******************************************************************************/
var doLinks  = (process.argv[2] || "").toLowerCase() == 'links';
var names    = Object.keys(packages);
var name;
var installed;
var links;

/*------------------------------------------*/
/* Get the list of installed packages for   */
/* version comparison and install packages. */
/*------------------------------------------*/
console.log('Configuring global Node environment...')
run('npm ls -g --json', function(stdout)
  {
  installed = JSON.parse(stdout).dependencies || {};
  doWhile();
  });

/*--------------------------------------------*/
/* Start of asynchronous package installation */
/* loop. Do until all packages installed.     */
/*--------------------------------------------*/
var doWhile = function()
  {
  if (name = names.shift())
    doWhile0();
  }

var doWhile0 = function()
  {
  /*----------------------------------------------*/
  /* Installed package specification comes from   */
  /* 'from' field of installed packages. Required */
  /* specification comes from the packages list.  */
  /*----------------------------------------------*/
  var current  = (installed[name] || {}).from;
  var required =   packages[name];

  /*---------------------------------------*/
  /* Install the package if not installed. */
  /*---------------------------------------*/
  if (!current)
    runCommand('npm install -g '+required, doWhile1);

  /*------------------------------------*/
  /* If the installed version does not  */
  /* match, uninstall and then install. */
  /*------------------------------------*/
  else if (current != required)
    {
    delete installed[name];
    runCommand('npm remove -g '+name, function() 
      {
      runCommand('npm remove '+name, doWhile0);
      });
    }

  /*------------------------------------*/
  /* Skip package if already installed. */
  /*------------------------------------*/
  else
    doWhile1();
  };

var doWhile1 = function()
  {
  /*-------------------------------------------------------*/
  /* Create link to global package from local environment. */
  /*-------------------------------------------------------*/
  if (doLinks && !fs.existsSync(path.join('node_modules', name)))
    runCommand('npm link '+name, doWhile);
  else
    doWhile();
  };

现在,如果我想为我们的开发人员更新一个全局工具,我更新“packages”对象并签入新的脚本。我的开发人员检查了它,要么用“node npm-setup.js”运行它,要么用任何正在开发的产品中的“npm install”来更新全局环境。整个过程需要5分钟。

此外,要为新开发人员配置环境,他们必须首先只安装Windows的NodeJS和GIT,重新启动计算机,检查“共享文件”文件夹和任何正在开发的产品,然后开始工作。

“包。.NET产品在安装之前调用这个脚本:

{ 
"name"                    : "Books",
"description"             : "Node (npm) configuration for Books Database Web Application Tools",
"version"                 : "2.1.1",
"private"                 : true,
"scripts":
  {
  "preinstall"            : "node ../../SharedFiles/npm-setup.js links",
  "postinstall"           : "bower install"
  },
"dependencies": {}
}

笔记

注意,即使在Windows中,脚本引用也需要正斜杠 环境。 “npm ls”将给出“npm ERR!”无关的:“所有包的消息 本地链接,因为它们不在“package.json”中列出 “依赖”。

编辑1/29/16

上面更新的npm-setup.js脚本修改如下:

Package "version" in var packages is now the "package" value passed to npm install on the command line. This was changed to allow for installing packages from somewhere other than the registered repository. If the package is already installed but is not the one requested, the existing package is removed and the correct one installed. For reasons unknown, npm will periodically throw an EBUSY error (-4082) when performing an install or link. This error is trapped and the command re-executed. The error rarely happens a second time and seems to always clear up.


你可以使用一个单独的文件,比如npm_globals.txt,而不是package.json。这个文件将包含每个模块,就像这样,

mongoose@1.4.0
node.io@0.3.3
jquery@1.5.1
jsdom@0.2.0
cron@0.1.2

然后在命令行中运行,

< npm_globals.txt xargs npm install -g

检查它们是否正确安装,

npm list -g --depth=0

至于你是否应该这样做,我认为这完全取决于用例。对于大多数项目,这是不必要的;拥有你的项目包。Json将这些工具和依赖项封装在一起是更可取的。

但现在我发现,当我跳上一台新机器时,我总是在全局安装create-react-app和其他CLI。当版本控制不太重要时,有一种简单的方法来安装一个全局工具及其依赖项是很好的。

现在,我使用npx,一个npm包运行器,而不是全局安装包。


构建自己的脚本来安装全局依赖项。这并不需要太多。包中。Json是相当可扩展的。

const { execSync } = require('child_process');
const fs = require('fs');

const package = JSON.parse(fs.readFileSync('package.json'));

let keys = Object.keys(package.dependencies);
let values = Object.values(package.dependencies);


for (let index = 0; index < keys.length; index++) {
    const key = keys[index];
    let value = values[index].replace("~", "").replace("^", "");

    console.log(`Installing: ${key}@${value} globally`,);
    execSync('npm i -g ' + `${key}@${value}`);
}

使用上面的,你甚至可以使它内联,下面!

请看下面的preinstall:

{
  "name": "Project Name",
  "version": "0.1.0",
  "description": "Project Description",
  "main": "app.js",
  "scripts": {
    "preinstall": "node -e \"const {execSync} = require('child_process'); JSON.parse(fs.readFileSync('package.json')).globalDependencies.forEach(globaldep => execSync('npm i -g ' + globaldep));\"",
    "build": "your transpile/compile script",
    "start": "node app.js",
    "test": "./node_modules/.bin/mocha --reporter spec",
    "patch-release": "npm version patch && npm publish && git add . && git commit -m \"auto-commit\" && git push --follow-tags"
  },
  "dependencies": [
  },
  "globalDependencies": [
    "cordova@8.1.2",
    "ionic",
    "potato"
  ],
  "author": "author",
  "license": "MIT",
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^5.2.0"
  },
  "bin": {
    "app": "app.js"
  }
}

节点的作者可能不承认包。Json是一个项目文件。但事实确实如此。


这可能是生产中出现问题的原因。 如果项目依赖项安装在项目文件夹之外,如果其他人删除或替换你的包或更改文件夹权限,代码可能会中断。

将所有东西都放在一个文件夹中更持久,使系统更可预测,维护任务也更容易。