动态地将文件插入到meteor公用文件夹中而不隐藏它

时间:2013-07-19 07:48:53

标签: meteor

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

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

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

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

那里还有其他解决方案吗?

4 个答案:

答案 0 :(得分: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流星文件夹
    • 使用点文件夹(例如隐藏文件夹ex:.uploads

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

答案 1 :(得分: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存储桶稳固且便宜。

答案 2 :(得分:3)

所以我用iron:router解决了这个问题。我创建了一个文件夹assets外面 meteor文件夹。然后,我有这样的代码来提供文件

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

我还使用了fspath模块的meteorhacks:npm模块。

答案 3 :(得分:0)

此套餐可能有所帮助:

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

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