是否可以自动下载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.
答案 0 :(得分:17)
是的,正好有一段名为NPM的代码:https://npmjs.org/
您可以在package.json
文件中指定相关的包(see the docs以获取语法),然后您可以使用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
答案 1 :(得分: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)
}
}
})
}
}
})()
答案 2 :(得分:0)
我受@Aminadav Glickshtein's answer的启发,创建了自己的脚本,该脚本将同步安装所需的模块,因为他的回答缺少这些功能。
我需要一些帮助,因此我提出了一个问题 here 。您可以了解该脚本的工作原理。
结果如下:
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()
答案 3 :(得分:0)
当我通过右键单击在Windows上打开脚本然后使用nodejs打开时,它将尝试在system32中安装节点模块,但失败
我修改了脚本,并且可以正常工作
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)};
完整:
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);
}
};