8

我有一个生成图像的流星应用程序。它们生成后,我想为它们服务。但是每次我写入公用文件夹时,我的流星服务器都会重新启动。我搜索了一个解决方案并找到了几个解决方法:

  • 在项目文件夹之外提供文件 - 目前我不知道如何实现这一点,我是否必须编写某种集成到流星中的中间件?

  • 在文件夹中添加波浪号 ~ public/- 这似乎使流星完全忽略该文件夹,当我尝试访问文件夹中的文件时,我被重定向到我的根页面。

  • 在生产模式下运行流星。对我来说似乎是一个肮脏的解决方法。现在,meteor run --production仍然重新启动我的服务器,所以我必须捆绑我的应用程序,每次都重新安装光纤,设置我的环境变量,然后运行应用程序。每次我改变一些东西。

还有其他解决方案吗?

4

4 回答 4

9

接受的答案对我不起作用,但从0.6.6.3版开始,您可以执行以下操作:

var fs = Npm.require('fs');
WebApp.connectHandlers.use(function(req, res, next) {
    var re = /^\/url_path\/(.*)$/.exec(req.url);
    if (re !== null) {   // Only handle URLs that start with /url_path/*
        var filePath = process.env.PWD + '/.server_path/' + re[1];
        var data = fs.readFileSync(filePath, data);
        res.writeHead(200, {
                'Content-Type': 'image'
            });
        res.write(data);
        res.end();
    } else {  // Other urls will have default behaviors
        next();
    }
});

笔记

  • process.env.PWD会给你项目根目录
  • 如果您打算将文件放入项目中

    • 不要使用publicprivate流星文件夹
    • 使用点文件夹(例如隐藏文件夹,例如.uploads:)

    不尊重这两个将导致本地流星在每次上传时重新启动,除非您运行您的流星应用程序:meteor run --production

于 2013-12-03T18:23:36.890 回答
7

那并没那么简单。

  • 写入public是没有问题的,因为 Meteor 管理这个文件夹,因此在每次文件更改时都会重新启动。

  • 写入被忽略的文件夹(以 开头.或结尾~,甚至在 Meteor 目录之外)是一种选择。但是,您需要手动提供这些文件。一个小的中间件就可以了:

 

__meteor_bootstrap__.app.stack.splice (0, 0, {
  route: '/mediaPathOfChoice',
  handle: function(req, res, next) {

    /* Read the proper file based on req.url */

    res.writeHead(200, {
      'Content-Type': /* Put the item MIME type here */
    });
    res.write(/* Put item contents here */);
    res.end();

  },

});

 

  • 对于许多发布选项,在应用程序服务器上写入文件无论如何都不是最好的解决方案。考虑为您的文件设置媒体服务器 - 为此目的,S3 存储桶既可靠又便宜。
于 2013-07-19T09:47:48.350 回答
3

所以我用iron:router解决了这个问题。我做了一个文件夹,assets,它在流星文件夹之外。然后我有这样的代码来提供文件

var fs = Npm.require('fs');
var path = Npm.require('path');

Router.map(function () {
  this.route('assets', {
    where: 'server',
    path: '/assets/:filename(.*)',
    action: function() {
      var basePath = process.env.ASSET_PATH;
      var filename = path.normalize(path.join(basePath, this.params.filename));
      var res = this.response;
      if (filename.substr(0, basePath.length) != basePath ||
          !fs.existsSync(filename) ||
          !fs.statSync(filename).isFile()) {
        res.writeHead(404, {'Content-Type': 'text/html'});
        res.end('404: no such asset: ' + this.params.filename);
        return;
      }
      var data = fs.readFileSync(filename);
      var mimeType = mime.lookup(filename);
      res.writeHead(200, { 'Content-Type': mimeType });
      res.write(data);
      res.end();
    },
  });
});

Mime 查找看起来像这样

var mime = {
  lookup: (function() {

    var mimeTypes = {
      ".html": "text/html",
      ".js":   "application/javascript",
      ".json": "application/json",
      ".png":  "image/png",
      ".gif":  "image/gif",
      ".jpg":  "image/jpg",
    };

    return function(name) {
      var type = mimeTypes[path.extname(name)];
      return type || "text/html";
    };
  }()),
};

该代码仅在服务器上执行,因此请将其放在服务器文件夹中或确保它处于if (Meteor.isServer)检查状态。

正如您在上面看到的,我使用环境变量作为资产文件夹的路径。所以我可以像这样运行流星

ASSET_PATH=/some/path/to/assets meteor

我还在为and模块使用meteorhacks:npm模块。fspath

于 2015-10-17T11:46:46.467 回答
0

该软件包可能会有所帮助:

CollectionFS 为您的 Meteor Web 应用程序添加了简单而强大的文件上传和下载功能。它是 Meteor.Collection 和 MongoDB 的 GridFS 的混合体。CollectionFS 将文件存储在您的 MongoDB 数据库中,但也提供了在服务器文件系统或远程文件系统上轻松存储文件的能力。

https://github.com/CollectionFS/Meteor-CollectionFS

于 2013-12-30T00:30:48.327 回答