【问题标题】:How can I deploy node modules in a Meteor app on meteor.com?如何在meteor.com 上的Meteor 应用程序中部署节点模块?
【发布时间】:2012-05-15 14:41:15
【问题描述】:

我有一个使用 node twit 模块的应用程序,该模块可通过

npm install twit

我从本地部署了节点模块 .meteor/local/build/server/

所以,它在 .meteor/local/build/server/node_modules/twit

我尝试在项目根目录安装它,但项目没有找到该模块。这使我找到了上述有效的解决方案。

我的应用程序现在在本地运行良好。我能够运行和做所有事情,并且可以根据我想要做的事情从我的 Meteor 服务器端或客户端与 Twitter 交互。没有崩溃。

当我通过命令部署到meteor.com时

meteor deploy [appname] --password

应用部署成功。

当我尝试从浏览器访问 (app at anonistream.meteor.com)[anonistream.meteor.com] 时失败并且日志包含此错误。

[Mon May 07 2012 01:59:53 GMT+0000 (UTC)] WARNING
node.js:201
   throw e; // process.nextTick error, or 'error' event on first tick
         ^
Error: Cannot find module 'twit'
at Function._resolveFilename (module.js:332:11)
at Function._load (module.js:279:25)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at app/server/server.js:2:12
at /meteor/containers/84162a7c-24e8-bf26-6fd8-e4ec13b2a935/bundle/server/server.js:111:21
at Array.forEach (native)
at Function.<anonymous>
 (/meteor/containers/84162a7c-24e8-bf26-6fd8-     e4ec13b2a935/bundle/server/underscore.js:76:11)
at /meteor/containers/84162a7c-24e8-bf26-6fd8-e4ec13b2a935/bundle/server/server.js:97:7
[Mon May 07 2012 01:59:53 GMT+0000 (UTC)] INFO STATUS running -> waiting
[Mon May 07 2012 01:59:53 GMT+0000 (UTC)] ERROR Application crashed with code: 1
[Mon May 07 2012 02:29:55 GMT+0000 (UTC)] INFO HIT / 24.94.158.145
[Mon May 07 2012 02:29:59 GMT+0000 (UTC)] INFO HIT /favicon.ico 24.94.158.145
[Mon May 07 2012 02:30:46 GMT+0000 (UTC)] INFO HIT / 24.94.158.145
[Mon May 07 2012 02:30:50 GMT+0000 (UTC)] INFO HIT /favicon.ico 24.94.158.145

有人对如何实现这一点有任何建议吗?

【问题讨论】:

  • 只是检查...但是你的package.json 文件中包含 twit 吗?
  • 我不知道我必须构建一个流星包才能在我的部署中包含 twit。我将不得不调查一下,看看是否是这种情况。我假设 node_modules 中的任何内容都直接被推送到部署中。我明天要去挖掘源代码,看看我能找到什么!除非其他人发布答案!
  • 老实说,我也不确定...期待听到其他人的意见。
  • 就个人而言,我现在有一个 package.json 用于我所有的流星项目。但是我现在只部署到 Heroku(对于具有节点依赖关系的高级应用程序)。方法如下:github.com/matb33/heroku-meteor-npm

标签: meteor


【解决方案1】:

从 Meteor 6.0 开始,现在我们需要使用 Npm.require() 来代替。此外,我们需要将模块声明为全局变量,因为 Meteor 现在具有文件级范围。

  var path = Npm.require('path');
  var fs = Npm.require('fs');
  var base = path.resolve('.');
  var isBundle = fs.existsSync(base + '/bundle');
  var modulePath = base + (isBundle ? '/bundle/static' : '/public') + '/node_modules';
  MODULE_NAME = Npm.require(modulePath + '/MODULE_NAME'); // NOTE, this is going to be a global variable

【讨论】:

  • 你能澄清一下在流星项目中放置 Npm.require() 语句的位置吗?
  • 那么当在 Meteor 中使用 npm 包时,你必须这样做,而不是仅仅使用 Meteor.require?如果 npm 模块位于 public/node_modules 文件夹中,那么 npm 模块是否在客户端和服务器上都可用?这种使用 npm 模块的方法是否会导致问题?我只是对将 npm 模块集成到我的项目中以在服务器上使用的最佳方法感到困惑。
  • @supertrue:我的评论有点晚了,但这是对频谱答案的一种回复(目前已接受的答案)。所以它可以在 app/server/server.js 中。
【解决方案2】:

最后,我是这样写的。 它适用于本地和流星服务器。谢谢伊恩:D

在“app/public”中安装 npm 模块:

app/public# npm install MODULE_NAME

在 app/server/server.js 内:

Meteor.startup(function () {
    var require = __meteor_bootstrap__.require;
    var path = require('path');
    var base = path.resolve('.');
    var isBundle = path.existsSync(base + '/bundle');
    var modulePath = base + (isBundle ? '/bundle/static' : '/public') + '/node_modules';

    var MODULE_NAME = require(modulePath + '/MODULE_NAME');
});

【讨论】:

  • Spectrum,你能提供任何例子吗?我不能让它工作。每次我对应用程序文件夹进行更改时,它都会在流星重新启动时被覆盖。
  • 好吧,我搞定了。必须添加这一行:var fs = require('fs'); 并修改:var isBundle = path.existsSync(base + '/bundle');var isBundle = fs.existsSync(base + '/bundle');
  • 注意:从 Meteor 0.6.0 开始,__meteor_bootstrap__.require 已被 Npm.require() 淘汰
  • 如果你想使用外部 npm 包。使用 Npm 智能包(atmosphere.meteor.com/package/npm)。它就像一个魅力:)
  • 这是 2 年前的做法。请查看其他答案。
【解决方案3】:

从 JonathanKingston 在流星 irc 上找到的答案。参考meteoric project

将节点模块放在项目公共目录中。

使用这样的代码来确保它加载。

var require = __meteor_bootstrap__.require;
var path = require("path");
var fs = require('fs');
var Twit;
var twitPath = 'node_modules/twit';

var base = path.resolve('.');
if (base == '/'){
  base = path.dirname(global.require.main.filename);   
}

var publicPath = path.resolve(base+'/public/'+twitPath);
var staticPath = path.resolve(base+'/static/'+twitPath);

if (path.existsSync(publicPath)){
  Twit = require(publicPath);
}
else if (path.existsSync(staticPath)){
  Twit = require(staticPath);
}
else{
  console.log('node_modules not found');
}

meteor deploy 在那之后应该可以工作,我把我的节点模块放在服务器目录中

【讨论】:

  • 您遗漏了允许您在 Meteor 上 require 的代码行:var require = __meteor_bootstrap__.require;。这让我有点不知所措,我知道很多人都被 IRC 指出来了。
  • path.existsSync() 现在是 fs.existsSync()
  • 注意:自 Meteor 0.6.0 起,__meteor_bootstrap__.require 已被Npm.require() 淘汰
【解决方案4】:

刚刚花了半个小时搞清楚“在app/public 中安装 npm 模块”这一步,我想我会为下一个人节省一些时间。从您应用的主目录中:

cd public
mkdir node_modules
npm install foo

默认情况下,npm install foo 会“本地”安装,但如果当前目录中没有 node_modules 文件夹,那么它会向上移动目录树来寻找一个。我最终将软件包安装在$HOME/node_modules/foo 而不是本地项目中。适合localhost,但不适合部署。

(感谢npm install locally 解决了我的根本问题。)

【讨论】:

  • 追问:过了一会儿,我找到了陨石包npm来做这种事情,它就像一个魅力。如果您最终来到这里,您可能需要查看Meteor Hacks 上的文章。
【解决方案5】:

此代码适用于我,meteor 0.8.x 和 node_modules 安装在我的应用程序的 ./public 中:

var path = Npm.require('path')
var fs = Npm.require('fs')
var base = path.resolve('.')
var isBundle = fs.existsSync(base + '/bundle')
var modulePath = base + (isBundle ? '/bundle/static' : '/../client/app') + '/node_modules/'

var twit  = Npm.require(modulePath+'rssparser')

在 ./public 中创建 packages.json 文件也是一个好主意,以便通过 npm 更轻松地进行更新/安装。

流星万岁!

【讨论】:

  • 在本地运行时,我可以在我的应用程序的根文件夹中安装 npm install 然后使用 Meteor.require('package') 但是当上传到 Meteor.com 测试服务器时,我必须这样做这边走。这和使用 Meteor.require() 一样吗?你有遇到过什么缺点吗?
【解决方案6】:

改变:

var modulePath = base + (isBundle ? '/bundle/static' : '/../client/app') + '/node_modules/'

到:

var modulePath = base + (isBundle ? '/bundle/static' : '/../web.browser/app') + '/node_modules/'

【讨论】:

  • 疯了!你在我需要的时候准确地击中了
【解决方案7】:

base = base + "/bundle"

让它工作。

【讨论】:

    猜你喜欢
    • 2014-08-08
    • 2015-11-08
    • 1970-01-01
    • 2019-02-14
    • 2015-01-16
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多