将一个通用的js全局命名空间a-Frame项目转换为es6模块



我有一个A-Frame项目,它的主组件street也依赖于同一repo中的其他组件和辅助函数。

当前在A-Frame场景中使用street组件需要从同一repo导入8个单独的js文件,每个文件都有自己的<script>标记。(代码/显示页(

相反,我更喜欢一个更简单的结构来只导入一个文件,但我宁愿不使用像webpack这样的捆绑器。我认为有一种ES6方法,但我对如何在允许组件访问其他文件中的功能的同时利用ES6导入感到困惑。换句话说,如何将导入的文件放入同一个命名空间中。

这个问题有帮助,但注释澄清了导入的函数不会自动添加到全局命名空间:ES6进口等效于require((,无出口

也许结构会是这样的?

// 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帧脚本放在<head>中,您会注意到没有defer属性。

A-Frame有点违背现代网络性能建议,但它有一个很好的理由:它不希望浏览器在运行之前呈现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/

最新更新