如何npm安装当前目录以及包含package.json文件的子目录?

时间:2021-02-19 07:24:56

I have a an application which is a web game server and say for example I have node_modules which I use in directory ./ and I have a proper package.json for those. it happens that in directory ./public/ I have a website being served which itself uses node_modules and also has a proper package.json for itself.

我有一个应用程序,它是一个网页游戏服务器,并说,例如我有node_modules我在目录./中使用,我有一个适当的package.json为那些。它发生在目录./public/我有一个服务的网站本身使用node_modules并且还有一个适当的package.json。

I know I can do this by navigating the directories. But is there a command or way to automate this so that it is easier for other developers to bootstrap the application in their system?

我知道我可以通过导航目录来做到这一点。但是有没有一个命令或方法来自动化这个,以便其他开发人员更容易在他们的系统中引导应用程序?

2 个解决方案

#1


13  

Assuming you are on Linux/OSX, you could try something like this:

假设您使用的是Linux / OSX,您可以尝试这样的方法:

find ./apps/* -maxdepth 1 -name package.json -execdir npm install \;

find ./apps/* -maxdepth 1 -name package.json -execdir npm install \;

Arguments:

参数:

./apps/* - the path to search. I would advise being very specific here to avoid it picking up package.json files in other node_modules directories (see maxdepth below).

./apps/* - 搜索路径。我建议在这里非常具体,以避免它在其他node_modules目录中获取package.json文件(参见下面的maxdepth)。

-maxdepth 1 - Only traverse a depth of 1 (i.e. the current directory - don't go into subdirectories) in the search path

-maxdepth 1 - 仅在搜索路径中遍历深度1(即当前目录 - 不进入子目录)

-name package.json - the filename to match in the search

-name package.json - 要在搜索中匹配的文件名

-execdir npm install \; - for each result in the search, run npm install in the directory that holds the file (in this case package.json). Note that the backslash escaping the semicolon has to be escaped itself in the JSON file.

-execdir npm install \; - 对于搜索中的每个结果,在保存文件的目录中运行npm install(在本例中为package.json)。请注意,转义分号的反斜杠必须在JSON文件中自行转义。

Put this in the postinstall hook in your root package.json and it will run everytime you do an npm install:

把它放在你的root.json根目录下的postinstall钩子里,它会在你每次进行npm安装时运行:

"scripts": {
    "postinstall": "find ./apps/* -name package.json -maxdepth 1 -execdir npm install \\;"
}

#2


0  

For cross-platform support (incl. Windows) you may try my solution. Pure Node.js

对于跨平台支持(包括Windows),您可以尝试我的解决方案。 Pure Node.js

Run it as a "preinstall" npm script

将其作为“预安装”npm脚本运行

const path = require('path')
const fs = require('fs')
const child_process = require('child_process')

const root = process.cwd()
npm_install_recursive(root)

function npm_install_recursive(folder)
{
    const has_package_json = fs.existsSync(path.join(folder, 'package.json'))

    if (!has_package_json && path.basename(folder) !== 'code')
    {
        return
    }

    // 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.
    if (has_package_json)
    {
        if (folder === root)
        {
            console.log('===================================================================')
            console.log(`Performing "npm install" inside root folder`)
            console.log('===================================================================')
        }
        else
        {
            console.log('===================================================================')
            console.log(`Performing "npm install" inside ${folder === root ? 'root folder' : './' + path.relative(root, folder)}`)
            console.log('===================================================================')
        }

        npm_install(folder)
    }

    for (let subfolder of subfolders(folder))
    {
        npm_install_recursive(subfolder)
    }
}

function npm_install(where)
{
    child_process.execSync('npm install', { cwd: where, env: process.env, stdio: 'inherit' })
}

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))
}

#1


13  

Assuming you are on Linux/OSX, you could try something like this:

假设您使用的是Linux / OSX,您可以尝试这样的方法:

find ./apps/* -maxdepth 1 -name package.json -execdir npm install \;

find ./apps/* -maxdepth 1 -name package.json -execdir npm install \;

Arguments:

参数:

./apps/* - the path to search. I would advise being very specific here to avoid it picking up package.json files in other node_modules directories (see maxdepth below).

./apps/* - 搜索路径。我建议在这里非常具体,以避免它在其他node_modules目录中获取package.json文件(参见下面的maxdepth)。

-maxdepth 1 - Only traverse a depth of 1 (i.e. the current directory - don't go into subdirectories) in the search path

-maxdepth 1 - 仅在搜索路径中遍历深度1(即当前目录 - 不进入子目录)

-name package.json - the filename to match in the search

-name package.json - 要在搜索中匹配的文件名

-execdir npm install \; - for each result in the search, run npm install in the directory that holds the file (in this case package.json). Note that the backslash escaping the semicolon has to be escaped itself in the JSON file.

-execdir npm install \; - 对于搜索中的每个结果,在保存文件的目录中运行npm install(在本例中为package.json)。请注意,转义分号的反斜杠必须在JSON文件中自行转义。

Put this in the postinstall hook in your root package.json and it will run everytime you do an npm install:

把它放在你的root.json根目录下的postinstall钩子里,它会在你每次进行npm安装时运行:

"scripts": {
    "postinstall": "find ./apps/* -name package.json -maxdepth 1 -execdir npm install \\;"
}

#2


0  

For cross-platform support (incl. Windows) you may try my solution. Pure Node.js

对于跨平台支持(包括Windows),您可以尝试我的解决方案。 Pure Node.js

Run it as a "preinstall" npm script

将其作为“预安装”npm脚本运行

const path = require('path')
const fs = require('fs')
const child_process = require('child_process')

const root = process.cwd()
npm_install_recursive(root)

function npm_install_recursive(folder)
{
    const has_package_json = fs.existsSync(path.join(folder, 'package.json'))

    if (!has_package_json && path.basename(folder) !== 'code')
    {
        return
    }

    // 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.
    if (has_package_json)
    {
        if (folder === root)
        {
            console.log('===================================================================')
            console.log(`Performing "npm install" inside root folder`)
            console.log('===================================================================')
        }
        else
        {
            console.log('===================================================================')
            console.log(`Performing "npm install" inside ${folder === root ? 'root folder' : './' + path.relative(root, folder)}`)
            console.log('===================================================================')
        }

        npm_install(folder)
    }

    for (let subfolder of subfolders(folder))
    {
        npm_install_recursive(subfolder)
    }
}

function npm_install(where)
{
    child_process.execSync('npm install', { cwd: where, env: process.env, stdio: 'inherit' })
}

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))
}