이것은 조금 낡았지만 요구 사항에 부딪 쳤으므로 여기에 내가 찾은 해결책이 있습니다.
문제 :
개발 팀은 AngularJS / Bootstrap으로 마이그레이션하는 많은 .NET 웹 응용 프로그램 제품을 유지 관리합니다. VS2010은 사용자 지정 빌드 프로세스에 쉽게 적합하지 않으며 개발자는 일상적으로 여러 제품 릴리스를 작업하고 있습니다. 우리의 VCS는 Subversion입니다 (저는 알고 있습니다. Git으로 이동하려고하지만 성가신 마케팅 직원이 너무 까다로워 요). 단일 VS 솔루션에는 여러 개의 별도 프로젝트가 포함됩니다. 직원들에게 동일한 노드 패키지 (걸프, 바우어 등)를 동일한 컴퓨터에 여러 번 설치할 필요없이 개발 환경을 초기화하는 일반적인 방법이 필요했습니다.
TL; DR :
.NET 제품에 대한 모든 로컬 필수 패키지뿐만 아니라 글로벌 Node / Bower 개발 환경을 설치하려면 "npm install"이 필요합니다.
글로벌 패키지는 아직 설치되지 않은 경우에만 설치해야합니다.
글로벌 패키지에 대한 로컬 링크는 자동으로 작성되어야합니다.
해결책:
우리는 이미 모든 개발자와 모든 제품이 공유하는 공통 개발 프레임 워크를 가지고 있으므로 필요할 때 글로벌 패키지를 설치하고 로컬 링크를 작성하는 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"개체를 업데이트하고 새 스크립트를 체크인하십시오. 내 개발자는이를 확인하고 "노드 npm-setup.js"또는 개발중인 모든 제품에서 "npm install"로 실행하여 글로벌 환경을 업데이트합니다. 전부 5 분이 걸립니다.
또한 새 개발자를위한 환경을 구성하려면 먼저 NodeJS 및 GIT for Windows를 설치하고 컴퓨터를 재부팅 한 다음 "공유 파일"폴더 및 개발중인 모든 제품을 확인한 후 작업을 시작해야합니다.
.NET 제품의 "package.json"은 설치하기 전에이 스크립트를 호출합니다.
{
"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": {}
}
노트
1/29/16 수정
npm-setup.js
위 의 업데이트 된 스크립트는 다음과 같이 수정되었습니다.
"version"패키지 var packages
는 이제 npm install
명령 행에 전달 된 "package"값 입니다. 등록 된 리포지토리가 아닌 다른 곳에서 패키지를 설치할 수 있도록 변경되었습니다.
패키지가 이미 설치되었지만 요청 된 패키지가 아닌 경우 기존 패키지가 제거되고 올바른 패키지가 설치됩니다.
알 수없는 이유로 설치 또는 링크를 수행 할 때 npm은 주기적으로 EBUSY 오류 (-4082)를 발생시킵니다. 이 오류는 갇히고 명령이 다시 실행됩니다. 오류는 두 번째로 거의 발생하지 않으며 항상 정리되는 것 같습니다.
"preferGlobal": true
package.json 내부에 모듈을 설정할 수 있습니다 .