The best way to run npm install for nested folders?

前端 未结 9 1763
北恋
北恋 2020-11-30 17:38

What is the most correct way to install npm packages in nested sub folders?

my-app
  /my-sub-module
  package.json
package.json
<
相关标签:
9条回答
  • 2020-11-30 18:29

    Use Case 1: If you want be able to run npm commands from within each subdirectory (where each package.json is), you will need to use postinstall.

    As I often use npm-run-all anyway, I use it to keep it nice and short (the part in the postinstall):

    {
        "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:*"
    }
    

    This has the added benefit that I can install all at once, or individually. If you don't need this or don't want npm-run-all as a dependency, check out demisx's answer (using subshells in postinstall).

    Use Case 2: If you will be running all npm commands from the root directory (and, for example, won't be using npm scripts in subdirectories), you could simply install each subdirectory like you would any dependecy:

    npm install path/to/any/directory/with/a/package-json
    

    In the latter case, don't be surprised that you don't find any node_modules or package-lock.json file in the sub-directories - all packages will be installed in the root node_modules, which is why you won't be able to run your npm commands (that require dependencies) from any of your subdirectories.

    If you're not sure, use case 1 always works.

    0 讨论(0)
  • 2020-11-30 18:30

    Adding Windows support to snozza's answer, as well as skipping of node_modules folder if present.

    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' })
    })
    
    0 讨论(0)
  • 2020-11-30 18:34

    If you want to run a single command to install npm packages in nested subfolders, you can run a script via npm and main package.json in your root directory. The script will visit every subdirectory and run npm install.

    Below is a .js script that will achieve the desired result:

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

    Note that this is an example taken from a StrongLoop article that specifically addresses a modular node.js project structure (including nested components and package.json files).

    As suggested, you could also achieve the same thing with a bash script.

    EDIT: Made the code work in Windows

    0 讨论(0)
提交回复
热议问题