如何使用带有 type=module 的脚本中的代码

IT技术 javascript import ecmascript-6 module
2021-01-30 14:53:09

我不明白为什么这个微不足道的代码不起作用:

索引.html:

<!doctype HTML>
<html>

<head>
  <script type="module" src="/showImport.js"></script>
</head>

<body>
  <button onclick="showImportedMessage();">Show Message</button>
</body>

</html>

显示导入.js:

import showMessage from '/show.js';

function showImportedMessage() {
    showMessage();
}

显示.js:

export default "Why do I need this?";

export function showMessage() {
    alert("Hello!");
}

它由 NPM http-server 提供服务当我连接 Chrome (v65) 时,我看到以下错误

(index):8 Uncaught ReferenceError: showImportedMessage is not defined
    at HTMLButtonElement.onclick ((index):8)
onclick @ (index):8

如果我摆脱type=module(并通过将showMessage函数放入正确的导入/导出showImport.js)一切正常,但这样做的全部目的是使用 modules

另外我不得不添加那个无用的export default声明,没有它Chrome会抱怨:

Uncaught SyntaxError: The requested module '/show.js' does not provide an export named 'default'

那么我在这里错过了什么?

1个回答
  1. 在module上下文中,变量不会自动全局声明。您必须将它们附加到window自己身上这是为了防止您在使用普通脚本标签时遇到的范围模糊问题。
  2. 导入/导出用法不正确。

如果你export function xyz,你必须import { xyz }

如果你export default function xyz,你必须import xyzimport { default as xyz }

有关module语法的更多信息,请参阅本文。

显示导入.js:

import { showMessage } from './show.js'

window.showImportedMessage = function showImportedMessage() {
    showMessage()
}

显示.js:

export function showMessage() {
    alert("Hello!")
}
分配给窗口很好。使您 100% 清楚地知道您正在向全局命名空间中添加一些内容(var在传统的非module脚本标记中没有明确说明的内容)。例如,在较大的项目中,如果您不小心,您可能会意外地拥有两个名为“user”的变量。良好的实践可以帮助避免类似的愚蠢问题,但是module会完全阻止它们发生。
2021-03-25 14:53:09
即使在 about:config 中将 seucity.fileurl.strictoriginpoliy 设置为 false,这也无法像 2021 年在 Firefox 中编写的那样工作。你如何让 index.html 中的 window 引用该函数,因为它没有。最好将其编写为包含 HTML 文件的完整示例。好像你猜到了这一点,但没有尝试。
2021-03-25 14:53:09
你能举出第1点的例子吗?有没有比分配给窗口更好/更好的方法?
2021-03-28 14:53:09
@ElMac 为了在module上下文中创建全局变量,您需要通过脚本标签将变量直接添加到 HTML,例如 <script> let myVar; </script>
2021-03-28 14:53:09
优秀的!非常感谢。这是一个比副本中的更好的答案。
2021-03-31 14:53:09