Is it possible to automatically install the required modules for a node.js script?

后端 未结 4 1028
离开以前
离开以前 2021-01-01 20:07

Is it possible to automatically download the required modules for a node.js script? I\'m wondering if it\'s possible to generate a list of required modules for a node.js scr

相关标签:
4条回答
  • 2021-01-01 20:27

    I was inspired by @Aminadav Glickshtein's answer to create a script of my own that would synchronously install the needed modules, because his answer lacks these capabilities.

    I needed some help, so I started an SO question here. You can read about how this script works there.
    The result is as follows:

    const cp = require('child_process')
    
    const req = async module => {
      try {
        require.resolve(module)
      } catch (e) {
        console.log(`Could not resolve "${module}"\nInstalling`)
        cp.execSync(`npm install ${module}`)
        await setImmediate(() => {})
        console.log(`"${module}" has been installed`)
      }
      console.log(`Requiring "${module}"`)
      try {
        return require(module)
      } catch (e) {
        console.log(`Could not include "${module}". Restart the script`)
        process.exit(1)
      }
    }
    
    const main = async () => {
      const http    = await req('http')
      const path    = await req('path')
      const fs      = await req('fs')
      const express = await req('express')
    
      // The rest of the app's code goes here
    }
    
    main()
    

    And a one-liner (139 characters!). It doesn't globally define child_modules, has no last try-catch and doesn't log anything in the console:

    const req=async m=>{let r=require;try{r.resolve(m)}catch(e){r('child_process').execSync('npm i '+m);await setImmediate(()=>{})}return r(m)}
    
    const main = async () => {
      const http    = await req('http')
      const path    = await req('path')
      const fs      = await req('fs')
      const express = await req('express')
    
      // The rest of the app's code goes here
    }
    
    main()
    
    0 讨论(0)
  • 2021-01-01 20:31

    Yes, there is a great piece of code called NPM for exactly this: https://npmjs.org/

    You specify dependent packages in a package.json file (see the docs for syntax) and you can use npm install . to pull them in all at once, and then require them from your script.

    Package.json syntax page: https://docs.npmjs.com/getting-started/using-a-package.json

    The first time you install a module, your can provide any number of modules to install, and add the --save argument to automatically add it to your package.json

    npm i --save dnode request bluebird
    

    The next time, someone will execute npm i it will automatically install all the modules specified in your package.json

    0 讨论(0)
  • 2021-01-01 20:34

    when I open the script on windows by right clicking then open with nodejs it tries to install the node modules in system32 and it fails

    I modified the script and it works

    oneliner:

    var req=async m=>{let r=require;try{r.resolve(m)}catch(e){console.log('Installing ' + m);r('child_process').execSync('npm i --prefix "'+__dirname+'" ' +m);await setImmediate(()=>{})}return r(m)};
    

    full:

    var cp = require('child_process');
    var req = async module => {
        try {
            require.resolve(module);
        } catch (e) {
            console.log(`Could not resolve "${module}"\nInstalling`);
            cp.execSync(`npm install --prefix "${__dirname}" ${module}`);
            await setImmediate(() => {});
            console.log(`"${module}" has been installed`);
        }
        console.log(`Requiring "${module}"`);
        try {
            return require(module);
        } catch (e) {
            console.log(`Could not include "${module}". Restart the script`);
            process.exit(1);
        }
    };
    
    0 讨论(0)
  • 2021-01-01 20:35

    I have written a script for this.
    Place it at the start of your script, and any uninstalled modules will be installed when you run it.

    (function () {
      var r = require
      require = function (n) {
        try {
          return r(n)
        } catch (e) {
          console.log(`Module "${n}" was not found and will be installed`)
          r('child_process').exec(`npm i ${n}`, function (err, body) {
            if (err) {
              console.log(`Module "${n}" could not be installed. Try again or install manually`)
              console.log(body)
              exit(1)
            } else {
              console.log(`Module "${n}" was installed. Will try to require again`)
              try{
                return r(n)
              } catch (e) {
                console.log(`Module "${n}" could not be required. Please restart the app`)
                console.log(e)
                exit(1)
              }
            }
          })
        }
      }
    })()
    
    0 讨论(0)
提交回复
热议问题