npm packages
중첩 된 하위 폴더 에 설치하는 가장 올바른 방법은 무엇입니까 ?
my-app
/my-sub-module
package.json
package.json
한하는 가장 좋은 방법은 무엇입니까 packages
의 /my-sub-module
경우 자동으로 설치 npm install
에서 실행은 my-app
?
답변
단일 명령을 실행하여 중첩 된 하위 폴더에 npm 패키지를 설치하려면 루트 디렉터리에서 npm
및 main package.json
을 통해 스크립트를 실행할 수 있습니다 . 스크립트는 모든 하위 디렉토리를 방문하여 npm install
.
다음은 .js
원하는 결과를 얻을 수 있는 스크립트입니다.
var fs = require('fs')
var resolve = require('path').resolve
var join = require('path').join
var cp = require('child_process')
var os = require('os')
// get library path
var lib = resolve(__dirname, '../lib/')
fs.readdirSync(lib)
.forEach(function (mod) {
var modPath = join(lib, mod)
// ensure path has package.json
if (!fs.existsSync(join(modPath, 'package.json'))) return
// npm binary based on OS
var npmCmd = os.platform().startsWith('win') ? 'npm.cmd' : 'npm'
// install folder
cp.spawn(npmCmd, ['i'], { env: process.env, cwd: modPath, stdio: 'inherit' })
})
이것은 모듈 식 프로젝트 구조 (중첩 된 구성 요소 및 파일 포함) 를 구체적으로 다루는 StrongLoop 기사 에서 가져온 예제 입니다.node.js
package.json
제안 된대로 bash 스크립트로도 동일한 결과를 얻을 수 있습니다.
편집 : Windows에서 코드 작동
답변
중첩 된 하위 디렉터리의 이름을 알고 있다면 설치 후 사용하는 것을 선호합니다. 에서 package.json
:
"scripts": {
"postinstall": "cd nested_dir && npm install",
...
}
답변
@Scott의 대답에 따르면 install | postinstall 스크립트는 하위 디렉토리 이름을 알고있는 한 가장 간단한 방법입니다. 이것이 여러 하위 디렉토리에 대해 실행하는 방법입니다. 예를 들어, monorepo 루트에 api/
, web/
및 shared/
하위 프로젝트가 있다고 가정합니다.
// In monorepo root package.json
{
...
"scripts": {
"postinstall": "(cd api && npm install); (cd web && npm install); (cd shared && npm install)"
},
}
답변
내 솔루션은 매우 유사합니다. 순수 Node.js
다음 스크립트 는 각 하위 폴더가 package.json
있고 실행 npm install
되는 한 모든 하위 폴더를 (재귀 적으로) 검사 합니다. 예외를 추가 할 수 있습니다. 폴더에 package.json
. 아래 예에서 이러한 폴더 중 하나는 “packages”입니다. “사전 설치”스크립트로 실행할 수 있습니다.
const path = require('path')
const fs = require('fs')
const child_process = require('child_process')
const root = process.cwd()
npm_install_recursive(root)
// Since this script is intended to be run as a "preinstall" command,
// it will do `npm install` automatically inside the root folder in the end.
console.log('===================================================================')
console.log(`Performing "npm install" inside root folder`)
console.log('===================================================================')
// Recurses into a folder
function npm_install_recursive(folder)
{
const has_package_json = fs.existsSync(path.join(folder, 'package.json'))
// Abort if there's no `package.json` in this folder and it's not a "packages" folder
if (!has_package_json && path.basename(folder) !== 'packages')
{
return
}
// If there is `package.json` in this folder then perform `npm install`.
//
// Since this script is intended to be run as a "preinstall" command,
// skip the root folder, because it will be `npm install`ed in the end.
// Hence the `folder !== root` condition.
//
if (has_package_json && folder !== root)
{
console.log('===================================================================')
console.log(`Performing "npm install" inside ${folder === root ? 'root folder' : './' + path.relative(root, folder)}`)
console.log('===================================================================')
npm_install(folder)
}
// Recurse into subfolders
for (let subfolder of subfolders(folder))
{
npm_install_recursive(subfolder)
}
}
// Performs `npm install`
function npm_install(where)
{
child_process.execSync('npm install', { cwd: where, env: process.env, stdio: 'inherit' })
}
// Lists subfolders in a folder
function subfolders(folder)
{
return fs.readdirSync(folder)
.filter(subfolder => fs.statSync(path.join(folder, subfolder)).isDirectory())
.filter(subfolder => subfolder !== 'node_modules' && subfolder[0] !== '.')
.map(subfolder => path.join(folder, subfolder))
}
답변
사람들이이 질문을 보게 될 경우를 대비하여 참고 용입니다. 이제 다음을 수행 할 수 있습니다.
- 하위 폴더에 package.json 추가
- 이 하위 폴더를 기본 package.json에 참조 링크로 설치합니다.
npm install --save path/to/my/subfolder
답변
사용 사례 1 : 각 하위 디렉터리 (각 package.json이있는)에서 npm 명령을 실행하려면 다음을 사용해야합니다.postinstall
.
npm-run-all
어쨌든 자주 사용 하기 때문에 멋지고 짧게 유지하기 위해 사용합니다 (설치 후 부분).
{
"install:demo": "cd projects/demo && npm install",
"install:design": "cd projects/design && npm install",
"install:utils": "cd projects/utils && npm install",
"postinstall": "run-p install:*"
}
한 번에 또는 개별적으로 설치할 수있는 추가 이점이 있습니다. 필요하지 않거나 원하지 않는 경우npm-run-all
종속성으로 demisx의 답변을 확인하십시오 (설치 후 하위 셸 사용).
사용 사례 2 : 루트 디렉터리에서 모든 npm 명령을 실행하려는 경우 (예를 들어 하위 디렉터리에서 npm 스크립트를 사용하지 않을 것임) 종속성과 같이 각 하위 디렉터리를 간단히 설치할 수 있습니다.
npm install path/to/any/directory/with/a/package-json
후자의 경우 하위 디렉토리에서 node_modules
또는 package-lock.json
파일을 찾을 수 없다는 사실에 놀라지 마십시오. 모든 패키지가 root에 설치 node_modules
되므로 npm 명령을 실행할 수 없습니다. 종속 항목이 필요합니다).
확실하지 않은 경우 사용 사례 1은 항상 작동합니다.
답변
snozza의 답변에 Windows 지원을 추가 하고 node_modules
폴더가있는 경우 건너 뜁니다 .
var fs = require('fs')
var resolve = require('path').resolve
var join = require('path').join
var cp = require('child_process')
// get library path
var lib = resolve(__dirname, '../lib/')
fs.readdirSync(lib)
.forEach(function (mod) {
var modPath = join(lib, mod)
// ensure path has package.json
if (!mod === 'node_modules' && !fs.existsSync(join(modPath, 'package.json'))) return
// Determine OS and set command accordingly
const cmd = /^win/.test(process.platform) ? 'npm.cmd' : 'npm';
// install folder
cp.spawn(cmd, ['i'], { env: process.env, cwd: modPath, stdio: 'inherit' })
})