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

tro*_*mgy 10 javascript import module ecmascript-6

我无法弄清楚为什么这个简单的代码不起作用:

index.html的:

<!doctype HTML>
<html>

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

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

</html>
Run Code Online (Sandbox Code Playgroud)

showImport.js:

import showMessage from '/show.js';

function showImportedMessage() {
    showMessage();
}
Run Code Online (Sandbox Code Playgroud)

show.js:

export default "Why do I need this?";

export function showMessage() {
    alert("Hello!");
}
Run Code Online (Sandbox Code Playgroud)

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

(index):8 Uncaught ReferenceError: showImportedMessage is not defined
    at HTMLButtonElement.onclick ((index):8)
onclick @ (index):8
Run Code Online (Sandbox Code Playgroud)

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

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

Uncaught SyntaxError: The requested module '/show.js' does not provide an export named 'default'
Run Code Online (Sandbox Code Playgroud)

那我在这里错过了什么?

kin*_*aro 26

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

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

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

    有关模块语法的更多信息,请参阅此文章.

考虑到这一点,这就是你最终的结果.

showImport.js:

import { showMessage } from '/show.js'

window.showImportedMessage = function showImportedMessage() {
    showMessage()
}
Run Code Online (Sandbox Code Playgroud)

show.js:

export function showMessage() {
    alert("Hello!")
}
Run Code Online (Sandbox Code Playgroud)

  • 分配给窗口就可以了。100% 清楚地表明您正在向全局命名空间中添加某些内容(传统非模块脚本标记中的“var”无法明确表示的内容)。例如,在较大的项目中,如果您不小心,您可能会意外地拥有两个名为“user”的变量。良好的实践可以帮助避免类似的愚蠢问题,但模块可以完全阻止它们发生。 (3认同)
  • @AndrewS 你能不能_不要_对问题的回答方式做出粗鲁的假设尽管如此,还是有一个错字;导入演出文件需要一个“./”。修复了这个问题,现在似乎可以工作了。即便如此,跨浏览器的差异仍然是一个迷宫,我无法解释一切。针对您的具体案例提出一个新问题会更有成效。 (3认同)
  • 优秀!非常感谢。这是一个比副本中的更好的答案。 (2认同)
  • 你能举出第1点的例子吗?有没有比分配给窗口更好/更好的方法? (2认同)