【问题标题】:Can I hot deploy Meteor client HTML files?我可以热部署 Meteor 客户端 HTML 文件吗?
【发布时间】:2023-03-11 01:57:02
【问题描述】:

Meteor 的惊人之处在于,您可以在本地开发时手动更新 HTML 文件,并且这些更改会在您保存文件时立即生效。我想采用相同的功能并将其带到我们部署的环境中。原因是我们希望允许我们的客户对 UI 进行更改,而无需重新部署应用程序,甚至不需要知道它是 Meteor 应用程序。他们可能会向列表视图添加新字段、向表单添加新字段、更改标签等。

到目前为止,我已经为他们创建了一种方法,可以使用 DSL 调用 REST 服务来描述这些更改并将其保存在 Mongo 中。然后我们有一个引擎会动态创建 HTML 模板来实现它。这一切都很好。

接下来,我正在尝试根据我对 Meteor DB 的订阅来热部署 Meteor HTML 文件,该订阅存储可以按需更改的内容。是否可以即时更新 Meteor 客户端文件系统,以便实现热部署?

在服务器发布方法上执行以下操作会导致ENOENT: no such directory 错误:

var result = decodeHTML(cheerio.html());
console.log(result);

// Output to file
fs.writeFile('../client/app/client/templates/request-base-template.html', result, function (err) {
    if (err) {
        console.log("error: " + err);
    }
    else {
        console.log("File saved successfully");
    }
});

【问题讨论】:

  • 什么是'/client/view/template.html'?您是否希望覆盖您的模板?
  • 在生产环境中,你甚至没有 html 文件,它们都被编译成 JS 代码,生成你在页面上看到的响应式 HTML
  • 我已经更新了路径以匹配实际存在的路径,但是是的,你是对的,它们被编译成 JS,所以这种方法是有缺陷的。所以我想我真正的问题是我可以根据我们存储在 MongoDB 中的 HTML 的一些新更新重新编译它们吗?
  • 您要解决的问题是什么。是的,您可以根据对 HTML 的更改动态编译模板,但这听起来不是最好的设计。如果您更详细地描述您的用例,可能有更好的解决方案纯粹基于模型更改? (不在视图上)
  • 在上面更新的问题中查看更具描述性的问题陈述和用例。我认为如果可以实现的话,这将是一个非常引人注目的用例,可以在我们的工作中推动更多 Meteor 采用。

标签: node.js meteor


【解决方案1】:

您是否同意您正在编写定制的 cms 系统?如果是这样,那么meteor中已经有几个cms系统了。

我发现扩展 http://azimuthc.ms/ 的早期版本很容易

他们在写这篇文章时基本上考虑到了你的需求。

(我没有连接到这个项目)

【讨论】:

  • 有点,但对内容的控制非常严格。换句话说,我们正在定义内容以使用某些页面、选项卡等以非常具体的方式布局。我们允许最终用户做的事情是使用预定义的样式更改这些选项卡/容器上的内容。尽管如此,看到有人在做这样的事情仍然很有趣。
【解决方案2】:

将文件保存到磁盘以期待“热代码推送重新加载”绝对是一种错误的方式。

Meteor 在开发模式下提供文件监视,它会重新编译您的整个应用程序并在您的浏览器中刷新页面,但这样做是为了开发人员的方便,而不是为您的应用程序运行时使用。事实上,在生产环境中部署时甚至不会提供文件监视功能。

但这是实现您的用例的一种方法。这需要更深入地了解 Meteor 在幕后为您所做的事情。

首先,您需要意识到 Meteor 在构建时会将您的模板(空格键模板)编译成它自己的 JS DSL (HTMLJS)。每个基于结构的模板都会发生类似的事情,无论是在运行时还是在构建时编译它们。 Meteor 在构建时执行它以提高效率。您可以在Meteor Manual, Blaze chapter 中阅读更多相关信息;

这里的高级点是:如果你有一个模板

<template name="bla">
  Hello {{name}}!
</template>

.. 它会被编译成这样的:

Template.__define__("bla", (function() {
  var view = this;
  return [ "Hello ", Blaze.View(function() {
    return Spacebars.mustache(view.lookup("name"));
  }), "!" ];
}));

明白了吗?太好了。

现在,您需要从用户那里获取这种模板并将它们编译成这个基于 JS 的 DSL。您可以使用内置的spacebars-compiler 包来实现。

// on the server!
Meteor.startup(function () {
  // imagine your template is actually coming from database or where you store your user-generated content
  var template = "<p>Hello {{name}}!</p>";
  console.log(SpacebarsCompiler.compile(template));
});

如果您将spacebars-compiler 添加到您的应用程序并运行它,它将打印一个很好的编译模板。这是一个现场演示:http://meteorpad.com/pad/4tHHAvjpcBQwLuN4K

完美,现在将这个编译好的模板以你想要的任何形式发送到客户端(通过数据库、通过 Meteor 方法或 REST API,没关系,只需将字符串获取到客户端即可)。

安装后,您可以将其附加到任何您想要的位置!

其中一种更简单的方法是在 JS 代码中注册模板:

// on the client! pretend you got the compiledTemplate string from the server
var compiledTemplate = '(function() { var view = this; return HTML.P("Hello ", Blaze.View(function() {return Spacebars.mustache(view.lookup("name")); }), "!");})';
Template.__define__("myAwesomeTemplate", eval(compiledTemplate));

然后使用UI.dynamic 之类的东西在页面上呈现它。您可以在这里观看现场演示:http://meteorpad.com/pad/LQJuoooBQjSdJenfW

【讨论】:

  • 我正在处理最后一个示例,但我的机器在没有良好互联网的情况下卡住了。剩下的我会在后面追加
  • 巧妙的技巧 Slava。谢谢。如果您使用 eval,请务必注意代码注入的可能性。
  • 谢谢斯拉瓦!其中大部分都如您所描述的那样工作,但我的应用程序并非微不足道,因为我有一个已经有正文等的主 index.html 以及我用于不同页面的子模板。基本上,我只想将编译后的代码放入相应的 HTML 页面中。如果我这样做:{{&gt; UI.dynamic template="srcTemplate"}} 我在 Meteor 启动时遇到异常,我的 HTML 格式错误。
  • 这是分开的,你定义一个返回字符串的助手。就是这样。
  • 是的,你是对的,但它显着改变了我最初为特定系统创建整个模板的模型。我必须将它分解为每个部分的离散助手。考虑到动态模板的好处,当然还是值得的!
猜你喜欢
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多