javascript - 从 html 文件访问导出的函数

标签 javascript import ecmascript-6

我正在尝试使用 Chrome v65 的一些 ES6 功能

我有以下文件:

base.js :

export function consoleLogger(message) {
    console.log(message);
}

ma​​in.js

import { consoleLogger } from './base.js';
consoleLogger('Some message');

utils.js

function sayMyName(name) {
    console.log(name);
}

imports.html

<!DOCTYPE html>
<html>
<head>
    <script src='./main.js' type='module'></script>
    <script src='./utils.js'></script>
</head>
<body>
    <script>
        sayMyName('Cool name');
    </script>
</body>
</html>

像这样使用一切似乎都很好,在控制台中我得到了

Cool name utils.js:2

Some message base.js:2

然而,让我们想象一下我需要一些额外数据以便为 consoleLogger 方法编写消息的场景。然后我想在 ma​​in.js

中有这样的东西
function logToConsole(msg) {
    consoleLogger(msg);
}

并且在imports.html

<script>
    sayMyName('Cool name');
    logToConsole('Send from log to console');
</script>

然后对于 logToConsole('Send from log to console'); 在控制台中调用我的 html 文件,我得到:

Uncaught ReferenceError: logToConsole is not defined at imports.html:10

所以从base.js导入consoleLogger没有问题,直接在main.js中调用,就没有问题包含另一个 .js 文件 (utils.js) 并从那里调用方法,但是如果我尝试调用在 main.js 中声明的方法,它在内部调用导入的方法我从上面得到了错误。看起来 main.js 中的方法是否引用导入的方法似乎并不重要。我只是注释了所有内容,只留下一个简单的方法

ma​​in.js

import { consoleLogger } from './base.js';

/*function logToConsole(msg) {
    consoleLogger(msg);
}

consoleLogger('Some message');*/

function randomStuff() {
    console.log('random stuff');
}

在控制台中我得到了这个错误:

imports.html:11 Uncaught ReferenceError: randomStuff is not defined at imports.html:11

有人可以向我解释这种行为的原因吗?

最佳答案

ES 模块(和一般的 JS 模块)的目的之一是防止全局范围的污染。

模块导出不应该泄漏到全局范围。模块的使用通常假定所有第一方代码都驻留在模块中。 logToConsole('Send from log to console') 转到主模块。

如果需要与全局范围进行互操作,则应在模块内将变量显式公开为全局变量:

window.logToConsole = function (msg) {
    consoleLogger(msg);
}

正如另一个答案已经提到的,仍然可能存在竞争条件,因为模块是异步加载的。脚本应推迟到文档准备就绪 - jQuery ready 事件或 native 对应事件:

<script>
document.addEventListener('DOMContentLoaded', () => {
    logToConsole('Send from log to console');
});
<script>

关于javascript - 从 html 文件访问导出的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50176213/

相关文章:

c++ - 如何在 VB.net 中包含/导入 C++ 应用程序

mysql - 仅将 CSV 的第二列导入 MySQL

javascript - 使用 "this": "TypeError: Cannot read property ' renderElapsedString' of undefined"导入函数并获取 props

javascript - 使用 nvd3.js 绘制具有堆叠条形图和折线图的图表?

javascript - 您可能需要一个适当的加载程序来处理此文件类型错误

javascript - jQuery 在一个又一个的 child 中淡入淡出

intellij-idea - 无法在 Intellij 中导入 java.awt.* 和 javax.swing.*

node.js - Babel 将异步到模块方法转换为带有 ES6 映射的 Bluebird

javascript - "$.getJSON is not a function"使用 babel-node 和 ES6 中的 jQuery

javascript - 为什么for循环后面加了分号仍然执行?