将通用js全局命名空间A-Frame项目转换为es6模块
Converting a common js global namespace A-Frame project into es6 modules
我有一个 A-Frame 项目,其主要组件 street
还依赖于同一存储库中的其他组件和辅助函数。
目前在 A-Frame 场景中使用 street
组件需要从同一个 repo 导入 8 个单独的 js 文件,每个文件都有自己的 <script>
标签。 (code / show page)
相反,我宁愿使用一种更简单的结构来只导入一个文件,但我宁愿不使用诸如 webpack 之类的打包器。我认为有一种 ES6 方法,但我对如何利用 ES6 导入同时仍然允许组件访问来自其他文件的函数感到困惑。换句话说,如何让导入的文件进入同一个命名空间。
这个问题有帮助,但评论澄清导入的函数不会自动添加到全局命名空间:
也许结构会是这样的?
// 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);
})
这可能行不通,正确的方法是什么?
上面建议的结构需要一些修正。
首先,将导出添加到辅助函数中。例如,
function helperFunction (variable) {
code (variable);
}
更改为
export function helperFunction (variable) {
code (variable);
}
(见)
在 street.js
中,我们还需要确保引用导入的模块对象(参见 MDN Creating a module object)
我们还需要更改 <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/
A-Frame 和 ES 模块不能很好地协同工作,我认为不使用像 Webpack 这样的捆绑器就没有解决方案。
简而言之, 如果您想为整个应用程序使用一个 <script>
元素,同时仍能很好地组织代码,我建议使用 Webpack,使用生成的包被同步加载到 HTML 文档的 <head>
中。 Webpack 可以使用 ES 模块,因此您仍然可以在构建过程中自由使用它们。
有关本机模块加载为何不起作用的更多详细信息:
您的代码需要进行一些更改才能使用原生 ES 模块,但第一个出现问题:加载模块的 <script>
元素需要 type="module"
属性。这有一个副作用:浏览器对待模块的方式与对待带有 defer attribute, meaning the script is executed after the DOM has been parsed. This is by design, as it leads to better initial page performance. Unfortunately A-Frame expects to run before the DOM has been parsed, and further it expects that you've initialized all of your components, systems, etc. before it runs. That is why they recommend putting the a-frame script in the <head>
的传统脚本标签的方式相同,您会注意到没有 defer
属性。
A-Frame 有点违背现代网络性能建议,但它有一个很好的理由:它不希望浏览器在运行前呈现 HTML,因为它使用 HTML 出于自己的目的。
这意味着直接在浏览器中使用原生 ES 模块不适用于 A-Frame 应用程序。
我有一个 A-Frame 项目,其主要组件 street
还依赖于同一存储库中的其他组件和辅助函数。
目前在 A-Frame 场景中使用 street
组件需要从同一个 repo 导入 8 个单独的 js 文件,每个文件都有自己的 <script>
标签。 (code / show page)
相反,我宁愿使用一种更简单的结构来只导入一个文件,但我宁愿不使用诸如 webpack 之类的打包器。我认为有一种 ES6 方法,但我对如何利用 ES6 导入同时仍然允许组件访问来自其他文件的函数感到困惑。换句话说,如何让导入的文件进入同一个命名空间。
这个问题有帮助,但评论澄清导入的函数不会自动添加到全局命名空间:
也许结构会是这样的?
// 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);
})
这可能行不通,正确的方法是什么?
上面建议的结构需要一些修正。
首先,将导出添加到辅助函数中。例如,
function helperFunction (variable) {
code (variable);
}
更改为
export function helperFunction (variable) {
code (variable);
}
(见
在 street.js
中,我们还需要确保引用导入的模块对象(参见 MDN Creating a module object)
我们还需要更改 <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/
A-Frame 和 ES 模块不能很好地协同工作,我认为不使用像 Webpack 这样的捆绑器就没有解决方案。
简而言之, 如果您想为整个应用程序使用一个 <script>
元素,同时仍能很好地组织代码,我建议使用 Webpack,使用生成的包被同步加载到 HTML 文档的 <head>
中。 Webpack 可以使用 ES 模块,因此您仍然可以在构建过程中自由使用它们。
有关本机模块加载为何不起作用的更多详细信息:
您的代码需要进行一些更改才能使用原生 ES 模块,但第一个出现问题:加载模块的 <script>
元素需要 type="module"
属性。这有一个副作用:浏览器对待模块的方式与对待带有 defer attribute, meaning the script is executed after the DOM has been parsed. This is by design, as it leads to better initial page performance. Unfortunately A-Frame expects to run before the DOM has been parsed, and further it expects that you've initialized all of your components, systems, etc. before it runs. That is why they recommend putting the a-frame script in the <head>
的传统脚本标签的方式相同,您会注意到没有 defer
属性。
A-Frame 有点违背现代网络性能建议,但它有一个很好的理由:它不希望浏览器在运行前呈现 HTML,因为它使用 HTML 出于自己的目的。
这意味着直接在浏览器中使用原生 ES 模块不适用于 A-Frame 应用程序。