让NodeJS应用程序使用NPM进行更新

Hej在那里,

我试图添加一些非传统的function到我的NodeJS应用程序,但我有一些麻烦。 我想要做的是以下几点:

我想从客户端更新我的服务器代码。 (如果您愿意,可以使用自动更新function。)

我第一次尝试使用NPM API并运行:

npm.commands.install([package], function(err, data) 

但是当然这会导致错误,告诉我NPM在服务器运行时无法安装。

我第二次尝试使用以下代码产生NPM更新:

  spawnProcess('npm', ['update'], { cwd: projectPath }, done); 

spawnProcess函数是一个通用的spawn函数:

 var projectPath = path.resolve(process.cwd()); var spawnProcess = function(command, args, options, callback) { var spawn = require('child_process').spawn; var process = spawn(command, args, options); var err = false; process.stdout.on('data', function(data) { console.log('stdout', data.toString()); }); process.stderr.on('data', function(data) { err = true; console.log('stderr', data.toString()); }); if (typeof callback === 'function') { process.on('exit', function() { if (!err) { return callback(); } }); } }; 

但是,这给了我一个“CreateProcessW:无法find文件”错误后的stderr。 我不知道我做错了什么。

如果一切都失败了,我认为有可能编写一个shell脚本查杀节点,更新应用程序,然后重新启动它。 就像是:

 kill -9 45728 npm update node server 

但我不知道这是否是一个合理的解决scheme,以及如何从节点服务器执行它。 当然,我宁愿有产卵function。

任何帮助是受欢迎的。 提前致谢!

所以我终于解决了这个问题。 如果有人感兴趣,我是如何做到这一点的:

我使用NPM API构build了一个函数来检查当前版本是否是最新的:

  exports.checkVersion = function(req, res) { npm.load([], function (err, npm) { npm.commands.search(["mediacenterjs"], function(err, data){ if (err){ console.log('NPM search error ' + err); return; } else{ var currentInfo = checkCurrentVersion(); for (var key in data) { var obj = data[key]; if(obj.name === 'mediacenterjs' && obj.version > currentInfo.version){ var message = 'New version '+obj.version+' Available'; res.json(message); } } } }); }); } var checkCurrentVersion = function(){ var info = {}; var data = fs.readFileSync('./package.json' , 'utf8'); try{ info = JSON.parse(data); }catch(e){ console.log('JSON Parse Error', e); } return info; }; 

如果版本不是最新的,我使用node-wget启动一个下载(在我的情况下是github master repo url):

 var wget = require('wget'); var download = wget.download(src, output, options); download.on('error', function(err) { console.log('Error', err); callback(output); }); download.on('end', function(output) { console.log(output); callback(output); }); download.on('progress', function(progress) { console.log(progress * 100); }); 

该callback启动@John Munsch“自助”脚本解压缩function的基础上,但我添加了一个检查,看看是否有一个以前的解压缩尝试,如果是这样,我删除该文件夹:

 if(fs.existsSync(dir) === false){ fs.mkdirSync(dir); } else { rimraf(dir, function (err) { if(err) { console.log('Error removing temp folder', err); } else { fileHandler.downloadFile(src, output, options, function(output){ console.log('Done', output); unzip(req, res, output, dir); }); } }); } console.log("Unzipping New Version..."); var AdmZip = require("adm-zip"); var zip = new AdmZip(output); zip.extractAllTo(dir, true); fs.openSync('./configuration/update.js', 'w'); 

openSync函数启动我的基于'NodeMon'的文件( https://github.com/jansmolders86/mediacenterjs/blob/master/server.js ),杀死服务器,因为它列出了对特定文件的更改。 最后它重新启动并启动以下function:

 function installUpdate(output, dir){ console.log('Installing update...'); var fsExtra = require("fs.extra"); fsExtra.copy(dir+'/mediacenterjs-master', './', function (err) { if (err) { console.error('Error', err); } else { console.log("success!"); cleanUp(output, dir); } }); } function cleanUp(output, dir) { console.log('Cleanup...'); var rimraf = require('rimraf'); rimraf(dir, function (e) { if(e) { console.log('Error removing module', e .red); } }); if(fs.existsSync(output) === true){ fs.unlinkSync(output); console.log('Done, restarting server...') server.start(); } } 

感谢所有帮助我的人!

未经testing!

你有没有尝试过“prestart” npm脚本句柄 ? 当然这意味着你会使用npm来运行你的服务器: npm start

在你的package.json(如果你有):

 { "scripts" : { "start" : "node server.js", "prestart" : "scripts/customScript.js" } } 

NPM启动命令隐式默认为“启动”:“node server.js” 。 如果你的服务器脚本叫做server.js,则不需要包含这个。 你可以在customScript.js上做你的npm安装,或者可以直接调用npm install,虽然我没有testing过。

您也可以使用环境variablesprocess.env.npm_package_scripts_prestart来分配/读取您的处理程序

它不使用NPM来完成它,但是这里有一个我之前放在一起的实验性实验,因为我希望能够使用Node.js来构build一个自我更新的应用程序,以便在人们的机器上安装(像SABnzbd +,Couch Potato或Plex媒体服务器)。

示例代码的Github在这里: https : //github.com/JohnMunsch/selfhelp

我得到了一个例子,当新版本可用时,它会自动通知您,然后下载,更新和重新启动。 即使你不是最终使用它,你应该能够从中得到一些想法。