[英]Converting a common js global namespace A-Frame project into es6 modules
我有一个 A-Frame 项目,它的主要组件street
还依赖于来自同一个仓库的其他组件和辅助函数。
目前在 A-Frame 场景中使用street
组件需要从同一个 repo 导入 8 个单独的 js 文件,每个文件都有自己的<script>
标签。 (代码/显示页面)
相反,我更喜欢一个更简单的结构来只导入一个文件,但我宁愿不使用诸如 webpack 之类的捆绑器。 我认为有一种 ES6 方法,但我对如何利用 ES6 导入同时仍允许组件访问其他文件中的功能感到困惑。 换句话说,如何将导入的文件放到同一个命名空间中。
这个问题有帮助,但评论澄清了导入的函数不会自动添加到全局命名空间: ES6 import 等价于 require() without exports
也许结构会是这样的?
// index.html
<script src="src/street.js" ></script>
<a-scene>
<a-entity street="dosomething"></a-entity>
</a-scene>
// helperFunctions1.js
function coolHelperFunction1a (variable) {
// useful code
}
// street.js
import 'helperFunctions1.js'
import 'helperFunctions2.js'
AFRAME.registerComponent('street', {
coolHelperFunction1a (variable);
})
那可能行不通,正确的方法是什么?
A-Frame 和 ES 模块不能很好地配合使用,而且我认为不使用 Webpack 之类的捆绑器就没有解决方案。
简而言之,如果您希望在整个应用程序中使用单个<script>
元素同时仍能很好地组织代码,我建议您使用 Webpack,生成的包会同步加载到 HTML 文档的<head>
中。 Webpack 可以使用 ES 模块,因此您仍然可以在构建过程中自由使用这些模块。
有关本机模块加载不起作用的更多详细信息:
您的代码需要对原生 ES 模块的使用进行一些更改,但第一个会出现问题:加载模块的<script>
元素需要type="module"
属性。 这有一个副作用:浏览器对待模块的方式与对待带有defer 属性的传统脚本标签的方式相同,这意味着脚本在 DOM 被解析后执行。 这是设计使然,因为它会带来更好的初始页面性能。 不幸的是,A-Frame 期望在解析 DOM之前运行,而且它还期望您在运行之前初始化所有组件、系统等。 这就是为什么他们建议将 a-frame 脚本放在<head>
中,您会注意到没有defer
属性。
A-Frame 有点违背现代 Web 性能建议,但它有一个很好的理由:它不希望浏览器在运行之前呈现 HTML,因为它使用 HTML 来实现自己的目的。
这一切都意味着直接在浏览器中使用原生 ES 模块不适用于 A-Frame 应用程序。
上面建议的结构需要一些修复。
首先,将导出添加到辅助函数。 例如,
function helperFunction (variable) {
code (variable);
}
更改为
export function helperFunction (variable) {
code (variable);
}
(请参阅如何从 JS 文件中导出所有函数? )
在street.js
,我们还需要确保引用它作为导入的模块对象(参见MDN 创建模块对象)
我们还需要更改<script>
标记以包含type="module"
以使用导入和导出关键字。
这是修改后的结构:
// index.html
<script src="src/street.js" type="module"></script>
<a-scene>
<a-entity street="dosomething"></a-entity>
</a-scene>
// helperFunctions1.js
export function coolHelperFunction1a (variable) {
// useful code
}
// street.js
import * as helperFunctions1 from 'helperFunctions1.js'
import * as helperFunctions2 from 'helperFunctions2.js'
AFRAME.registerComponent('street', {
helperFunctions1.coolHelperFunction1a(variable);
})
另一种选择,不要使用 ES6 模块,而是使用 webpack。 这是 webpack A-Frame 组件项目的一个很好的例子: https ://github.com/supermedium/superframe/blob/master/components/state/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.