首页 文章

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

提问于
浏览
8

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

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

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

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

还有其他解决方案吗?

4 回答

  • 3

    接受的答案对我不起作用,但从版本 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

  • 9

    那并没那么简单 .

    • 写入 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存储桶稳固且便宜 .
  • 0

    所以我用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
    

    我还将meteorhacks:npm模块用于 fspath 模块 .

  • 7

    这个包可能有所帮助:

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

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

相关问题