Solución:
Nueva nota: Probablemente no quieras o no necesites hacer esto. Lo que probablemente quiera hacer es simplemente poner esos tipos de dependencias de comando para compilación / prueba, etc.en el devDependencies
sección de su package.json. Cada vez que usa algo de scripts
en package.json sus comandos devDependencies (en node_modules / .bin) actúan como si estuvieran en su camino.
Por ejemplo:
npm i --save-dev mocha # Install test runner locally
npm i --save-dev babel # Install current babel locally
Luego, en package.json:
// devDependencies has mocha and babel now
"scripts": {
"test": "mocha",
"build": "babel -d lib src",
"prepublish": "babel -d lib src"
}
Luego, en el símbolo del sistema, puede ejecutar:
npm run build # finds babel
npm test # finds mocha
npm publish # will run babel first
Pero si tu De Verdad desea instalar globalmente, puede agregar una preinstalación en la sección de scripts del package.json:
"scripts": {
"preinstall": "npm i -g themodule"
}
Así que en realidad mi npm install ejecuta npm install de nuevo … lo cual es extraño pero parece funcionar.
Nota: es posible que tenga problemas si está utilizando la configuración más común para npm
donde se requiere la instalación del paquete de nodo global sudo
. Una opción es cambiar su npm
configuración para que esto no sea necesario:
npm config set prefix ~/npm
, agregue $ HOME / npm / bin a $ PATH agregando export PATH=$HOME/npm/bin:$PATH
para usted ~/.bashrc
.
Debido a las desventajas que se describen a continuación, recomendaría siguiendo la respuesta aceptada:
Usar
npm install --save-dev [package_name]
luego ejecute scripts con:$ npm run lint $ npm run build $ npm test
Mi original pero no recomendado la respuesta sigue.
En lugar de utilizar una instalación global, puede agregar el paquete a su devDependencies
(--save-dev
) y luego ejecute el binario desde cualquier lugar dentro de su proyecto:
"$(npm bin)/<executable_name>" <arguments>...
En tu caso:
"$(npm bin)"/node.io --help
Este ingeniero proporcionó una npm-exec
alias como atajo. Este ingeniero usa un shellscript llamado env.sh
. Pero prefiero usar $(npm bin)
directamente, para evitar cualquier archivo o configuración adicional.
Aunque hace que cada llamada sea un poco más grande, debería solo trabajo, previniendo:
- posibles conflictos de dependencia con paquetes globales (@nalply)
- la necesidad de
sudo
- la necesidad de configurar un prefijo npm (aunque recomiendo usar uno de todos modos)
Desventajas:
-
$(npm bin)
no funcionará en Windows. - Las herramientas más profundas de su árbol de desarrollo no aparecerán en el
npm bin
carpeta. (Instale npm-run o npm-which para encontrarlos).
Parece una mejor solucion es colocar tareas comunes (como construir y minificar) en la sección “scripts” de su package.json
, como Jason demuestra arriba.
Esto es un poco antiguo, pero cumplí con el requisito, así que aquí está la solución que se me ocurrió.
El problema:
Nuestro equipo de desarrollo mantiene muchos productos de aplicaciones web .NET que estamos migrando a AngularJS / Bootstrap. VS2010 no se presta fácilmente a procesos de construcción personalizados y mis desarrolladores trabajan de forma rutinaria en múltiples versiones de nuestros productos. Nuestro VCS es Subversion (lo sé, lo sé. Estoy tratando de cambiarme a Git, pero mi molesto personal de marketing es muy exigente) y una única solución de VS incluirá varios proyectos separados. Necesitaba que mi personal tuviera un método común para inicializar su entorno de desarrollo sin tener que instalar los mismos paquetes de Nodo (gulp, bower, etc.) varias veces en la misma máquina.
TL; DR:
-
Necesita “npm install” para instalar el entorno de desarrollo global Node / Bower, así como todos los paquetes necesarios localmente para un producto .NET.
-
Los paquetes globales deben instalarse solo si aún no están instalados.
-
Los enlaces locales a paquetes globales deben crearse automáticamente.
La solución:
Ya tenemos un marco de desarrollo común compartido por todos los desarrolladores y todos los productos, así que creé un script NodeJS para instalar los paquetes globales cuando sea necesario y crear los enlaces locales. El script reside en “…. SharedFiles” en relación con la carpeta base del producto:
/*******************************************************************************
* $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" : "[email protected]",
"event-stream" : "[email protected]",
"gulp" : "[email protected]",
"gulp-angular-templatecache" : "[email protected]",
"gulp-clean" : "[email protected]",
"gulp-concat" : "[email protected]",
"gulp-debug" : "[email protected]",
"gulp-filter" : "[email protected]",
"gulp-grep-contents" : "[email protected]",
"gulp-if" : "[email protected]",
"gulp-inject" : "[email protected]",
"gulp-minify-css" : "[email protected]",
"gulp-minify-html" : "[email protected]",
"gulp-minify-inline" : "[email protected]",
"gulp-ng-annotate" : "[email protected]",
"gulp-processhtml" : "[email protected]",
"gulp-rev" : "[email protected]",
"gulp-rev-replace" : "[email protected]",
"gulp-uglify" : "[email protected]",
"gulp-useref" : "[email protected]",
"gulp-util" : "[email protected]",
"lazypipe" : "[email protected]",
"q" : "[email protected]",
"through2" : "[email protected]",
/*---------------------------------------------------------------*/
/* 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();
};
Ahora, si quiero actualizar una herramienta global para nuestros desarrolladores, actualizo el objeto “paquetes” y verifico el nuevo script. Mis desarrolladores lo revisan y lo ejecutan con “node npm-setup.js” o con “npm install” desde cualquiera de los productos en desarrollo para actualizar el entorno global. Todo tarda 5 minutos.
Además, para configurar el entorno para un nuevo desarrollador, primero solo deben instalar NodeJS y GIT para Windows, reiniciar su computadora, verificar la carpeta “Archivos compartidos” y cualquier producto en desarrollo, y comenzar a trabajar.
El “package.json” para el producto .NET llama a este script antes de la instalación:
{
"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": {}
}
Notas
-
Tenga en cuenta que la referencia de la secuencia de comandos requiere barras inclinadas incluso en un entorno de Windows.
-
“npm ls” dará mensajes “npm ERR! extraños:” para todos los paquetes enlazados localmente porque no están listados en las “dependencias” de “package.json”.
Editar 29/01/16
El actualizado npm-setup.js
El script anterior se ha modificado de la siguiente manera:
-
Paquete “versión” en
var packages
es ahora el valor del “paquete” que se pasa anpm install
en la línea de comando. Esto se cambió para permitir la instalación de paquetes desde algún lugar que no sea el repositorio registrado. -
Si el paquete ya está instalado pero no es el solicitado, se elimina el paquete existente y se instala el correcto.
-
Por razones desconocidas, npm arrojará periódicamente un error EBUSY (-4082) al realizar una instalación o un enlace. Este error queda atrapado y el comando se vuelve a ejecutar. El error rara vez ocurre una segunda vez y parece que siempre desaparece.