16

是否可以自动下载 node.js 脚本所需的模块?我想知道是否可以为 node.js 脚本(如下所示)生成所需模块的列表,并自动安装它们,而不是手动安装它们,一个接一个(使用 npm)。

#!/usr/bin/env node

var DNode = require('dnode');
var sys = require('sys');
var fs = require('fs');
var http = require('http');

var html = fs.readFileSync(__dirname + '/web.html');
var js = require('dnode/web').source();

//the rest of this script is omitted.
4

4 回答 4

18

是的,有一段很棒的代码叫做 NPM 就是为了这个:https ://npmjs.org/

您在文件中指定依赖包package.json请参阅文档以了解语法),您可以使用npm install .一次将它们全部拉入,然后require从脚本中提取它们。

Package.json 语法页面:https ://docs.npmjs.com/getting-started/using-a-package.json

首次安装模块时,您可以提供任意数量的模块来安装,并添加--save参数以自动将其添加到您的package.json

npm i --save dnode request bluebird

下次有人会执行npm i它会自动安装你指定的所有模块package.json

于 2013-01-08T23:54:18.390 回答
5

我为此写了一个脚本。
将它放在脚本的开头,当你运行它时,所有卸载的模块都会被安装。

(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)
          }
        }
      })
    }
  }
})()
于 2014-02-03T10:37:06.240 回答
0

我受到@Aminadav Glickshtein 的回答的启发,创建了一个我自己的脚本来同步安装所需的模块,因为他的回答缺乏这些功能。

我需要一些帮助,所以我在这里开始了一个 SO 问题。您可以在那里阅读有关此脚本如何工作的信息。
结果如下:

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

还有一个单行字(139 个字符!)。它没有全局定义child_modules,没有最后一个try-catch,也没有在控制台中记录任何内容:

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()
于 2018-11-19T22:23:37.667 回答
0

当我通过右键单击在 Windows 上打开脚本然后使用 nodejs 打开时,它尝试在 system32 中安装节点模块,但它失败了

我修改了脚本并且它有效

单线:

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

满的:

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);
    }
};
于 2020-03-03T03:07:56.803 回答