在嵌套子文件夹中安装npm包的最正确方法是什么?

my-app
  /my-sub-module
  package.json
package.json

当npm install在my-app中运行时,在/my-sub-module中自动安装包的最佳方法是什么?


当前回答

接受的答案是有效的,但是你可以使用——prefix在选定的位置运行npm命令。

"postinstall": "npm --prefix ./nested_dir install"

——prefix适用于任何npm命令,而不仅仅是install。

还可以查看当前前缀with

npm prefix

并将全局安装(-g)文件夹设置为

npm config set prefix "folder_path"

也许是TMI,但你懂的…

其他回答

接受的答案是有效的,但是你可以使用——prefix在选定的位置运行npm命令。

"postinstall": "npm --prefix ./nested_dir install"

——prefix适用于任何npm命令,而不仅仅是install。

还可以查看当前前缀with

npm prefix

并将全局安装(-g)文件夹设置为

npm config set prefix "folder_path"

也许是TMI,但你懂的…

[macOS、Linux用户]:

我创建了一个bash文件来安装项目和嵌套文件夹中的所有依赖项。

find . -name node_modules -prune -o -name package.json -execdir npm install \;

解释:在根目录中,排除node_modules文件夹(即使在嵌套文件夹中),找到包含包的目录。Json文件,然后运行NPM install命令。

如果你只是想找到指定的文件夹(例如:abc123, def456文件夹),运行如下:

find ./abc123/* ./def456/* -name node_modules -prune -o -name package.json -execdir npm install \;

只是作为参考,以防人们遇到这个问题。你现在可以:

添加包。Json到子文件夹中 在main package.json中安装这个子文件夹作为reference-link:

NPM安装——保存路径/到/my/子文件夹

如果你想在嵌套的子文件夹中运行一个命令来安装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项目结构(包括嵌套组件和包)。json文件)。

如前所述,您也可以使用bash脚本实现相同的功能。

编辑:使代码在Windows工作

我的解决方案非常相似。 纯粹的node . js

下面的脚本检查所有子文件夹(递归地),只要它们有包。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))
}