在 Meteor 项目中使用 ES6 `import` 和 CSS/HTML 文件:错误还是功能?

Posted

技术标签:

【中文标题】在 Meteor 项目中使用 ES6 `import` 和 CSS/HTML 文件:错误还是功能?【英文标题】:Using ES6 `import` with CSS/HTML files in Meteor project: bug or feature? 【发布时间】:2016-07-06 10:17:35 【问题描述】:

我目前正在学习 Meteor,我发现了一些让我感兴趣的东西。

我可以使用 import 语句从 JS 文件中加载 html 和 CSS 资源。

import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
import * as myApp from '../imports/hello/myapp.js';

这让我很惊讶,所以我跑到 google,但在 ES6 import 的规范或 Meteor 的文档中找不到这种行为。

所以我的问题是:

我可以依靠这种行为来构建我的应用程序吗? 当 Meteor 修复它时,我的应用程序是否会崩溃——如果它是一个错误——?

备注

我正在使用 Meteor v1.3,不确定这是否也适用于以前的版本。 您可以从Github 下载应用程序以查看此行为

【问题讨论】:

为什么要将 CSS 和 HTML 导入 javascript 文件?您不需要在 Meteor 中执行此操作。 当然,还有其他方法可以达到同样的效果。问题仍然存在,是错误还是功能? 流星社区,你在哪里?快来接受这个赏金吧!!! 【参考方案1】:

在为我的应用完成构建文件的实现之后 我发现了为什么会这样。

HTML

从文件系统中读取文件并将其内容添加到全局模板对象中,例如,

== myapp.html ==

<body>
  <h1>Welcome to Meteor!</h1>
  > hello
</body>

结果如下 JS 代码:

Template.body.addContent((function ()                                                                        
  var view = this;                                                                                          
  return [
     HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n  "),      
     Spacebars.include(view.lookupTemplate("hello"))
  ];
));                                                                                                        

它被包裹在一个以文件名作为键的函数中:

"myapp.html": function (require, exports, module) 

     Template.body.addContent((function ()                                                                        
          var view = this;                                                                                          
          return [
             HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n  "),   
             Spacebars.include(view.lookupTemplate("hello"))]; 
     )); 

     Meteor.startup(Template.body.renderToDocument);                                                              

     Template.__checkName("hello");                                                                               
     Template["hello"] = new Template("Template.hello", (
         function ()                                             
           var view = this;                                                                                         
           return [
               HTML.Raw("<button>Click Me</button>\n  "), 
               HTML.P("You've pressed the button ", 
                      Blaze.View("lookup:counter", 
                      function () 
                        return Spacebars.mustache(view.lookup("counter"));                                                   
                      ), " times.")
          ];                                                                                         
     ));                                                                                                         

,

所以我们所有的 HTML 现在都是纯 JS 代码,可以像任何其他模块一样使用 require 来包含这些代码。

CSS

文件也从文件系统中读取,其内容也嵌入到 JS 函数中,例如

== myapp.css ==

/* CSS declarations go here */

body 
    background-color: lightblue;

转化为:

"myapp.css": ["meteor/modules", function (require, exports, module) 
    module.exports = require("meteor/modules").addStyles("/* CSS declarations go here */\n\nbody \n    background-color: lightblue;\n\n");

]

所以我们所有的 CSS 现在也是一个 JS 模块,稍后会使用 require 再次导入。

结论

所有文件都以一种或另一种方式转换为 JS 模块,这些模块遵循与 AMD/CommonJS 模块类似的包含规则。 如果另一个模块引用它们,它们将被包含/捆绑。并且由于它们都被转换为 JS 代码 欺骗性语法背后没有魔法:

import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';

一旦资产转换为 JS 模块,它们都将被转换为具有 require 的等效形式。

而官方文档中并没有提到将静态资产放在imports目录下的方法, 这种导入静态资产的方式有效。

这似乎是 Meteor 工作方式的核心,所以我敢打赌,这个功能会持续很长时间。

我不知道是否将此称为功能也许更恰当的描述是意想不到的结果,但那会 仅从用户的角度来看是正确的,我假设编写代码的人理解这会发生,甚至可能 故意这样设计的。

【讨论】:

只是出于好奇,您在哪里找到这些compiled HTML/CSS 代码? .meteor/local/build/programs/web.browser/app/app.js 您可以将.. 放在您的“../imports”中,显然您可以使用/imports/...,这样您就无需跟踪要达到多少级。 如何处理这样导入的文件? import '../imports/hello/myapp.html';import mytemplate ??? '../imports/hello/myapp.html';【参考方案2】:

Meteor 1.3 中的一个功能是延迟加载,您可以将文件放在/imports 文件夹中,并且不会被急切地评估。

来自 Meteor Guide 的引述:

充分利用模块系统并确保我们的代码仅在以下情况下运行 我们要求它,我们建议您的所有应用程序代码都应该是 放置在 imports/ 目录中。这意味着 Meteor 构建 系统只会捆绑并包含该文件,如果它被引用 使用导入的另一个文件。

因此,您可以通过从 /imports 文件夹导入 css 文件来延迟加载它们。我会说这是一个功能。

【讨论】:

这并不能解释为什么我们能够导入 CSS 和 HTML 文件等静态资源。 延迟加载、css模块、jss等。这就是为什么你需要在你的js文件中导入css。我不确定 html 导入的用例是什么。【参考方案3】:

ES6 导出和导入功能在 Meteor 1.3 中可用。如果您使用的是当前默认模板引擎 Blaze,则不应导入 HTML 和 CSS 文件。导入/导出功能已经存在,但您可能使用了错误的方法来构建视图。

【讨论】:

我现在知道这不是标准方法。问题仍然存在:错误还是功能? 也没有?您可以导入和导出。什么是错误? 我问这个问题的原因是我从没想过能够通过使用import 关键字来包含 HTML 和 CSS 文件。就像问题说的那样,我还没有找到任何解释这种行为的文档。我喜欢这样一个事实,即我可以显式导入任何资产,而不必将它们放在特殊的地方,然后依赖于神奇的加载机制,这就是为什么我想知道这种行为是否会一直存在,或者它会在某些时候被禁用未来的点。 ES6 导入和导出仅适用于 javascript 文件。这与 Meteor 无关。 没错,这就是我的想法,它应该只适用于 JS 文件。问题是:为什么它也适用于 HTML 和 CSS 文件?

以上是关于在 Meteor 项目中使用 ES6 `import` 和 CSS/HTML 文件:错误还是功能?的主要内容,如果未能解决你的问题,请参考以下文章

ES6 angular-meteor ng-table getData 函数未调用

在 Meteor 1.3 + angular1 上使用 npm(凹凸!)

如何在 Cordova 项目中嵌入 Meteor 视图?

我们如何或可以通过 npm 和 Meteor 使用节点模块?

如何组织 Meteor 项目中的文件夹和文件?

Bluemix/CloudFoundry + Meteor - 如何重置项目?