在Meteor项目中使用ES6`import`和CSS/HTML文件:bug或功能?

pgp*_*lla 15 html css import meteor ecmascript-6

我正在学习Meteor,我发现了一些让我着迷的东西.

我可以使用import语句从JS文件加载HTML和CSS资源.

import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
import * as myApp from '../imports/hello/myapp.js';
Run Code Online (Sandbox Code Playgroud)

这对我来说是一个惊喜所以我跑到谷歌但是在ES6规范import或Meteor的文档中找不到这种行为.

所以我的问题是:

  • 我可以依靠这种行为来构建我的应用程序吗?
  • 当Meteor到处修复它时,我的应用程序会破坏 - 如果它是一个bug - ?

笔记

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

pgp*_*lla 13

在完成我的应用程序的构建文件的实现后,我发现了为什么这样做.

HTML

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

== myapp.html ==

<body>
  <h1>Welcome to Meteor!</h1>
  {{> hello}}
</body>
Run Code Online (Sandbox Code Playgroud)

得到以下JS代码:

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

它包含在一个函数中,文件名是密钥:

"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.")
          ];                                                                                         
     }));                                                                                                         

},
Run Code Online (Sandbox Code Playgroud)

所以我们所有的HTML现在都是纯JS代码,它将require像任何其他模块一样使用.

CSS

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

== myapp.css ==

/* CSS declarations go here */

body {
    background-color: lightblue;
}
Run Code Online (Sandbox Code Playgroud)

变成:

"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");

}]
Run Code Online (Sandbox Code Playgroud)

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

结论

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

import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
Run Code Online (Sandbox Code Playgroud)

require一旦资产转换为JS模块,它们都被转换为等效形式.

虽然imports官方文档中没有提到在目录中放置静态资产的方法,但这种导入静态资产的方式仍然有效.

这似乎是Meteor如何工作的核心所以我敢打赌这个功能将会存在很长一段时间.

我不知道是否称这个功能可能是一个更合适的描述是意想不到的结果但是从用户的角度来看这只是真的,我认为编写代码的人理解这种情况会发生,甚至可能是故意这样设计的.