如果我使用ES6模块,是否仍需要一个模块加载器?

11

很不幸,我对于 JavaScript 模块加载器的了解还在逐渐增长,并且我正在尝试理解它们与新的 ES6 Modules 的关系。据我所知,使用像 CommonJS 或者 RequireJS 这样的模块加载器在 ES5 兼容的 JavaScript 中确实需要使用异步模块加载器才能提高性能并仅在需要时使用相应的模块加载器语法进行加载。

然而,查看 ES6 模块文档和阅读其他信息后,我发现模块加载是通过 importexport 关键字本地支持的。如果是这样的话,我是否正确地认为 ES6 JS 模块 本地支持异步模块加载,因此我不需要使用像 CommonJS 或者 RequireJS 这样的附加工具了?


小心使用“native”这个词——在什么情况下是本地的?import/export语句目前还没有得到浏览器/node等的官方支持,但可以通过诸如Babel之类的转换器来实现支持。(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) - Nick Zuber
@Supersharp 肯定是在一个标志后面吧?浏览器模块加载规范尚未最终确定,所以如果这是主流,我会感到惊讶。 - CodingIntrigue
3个回答

8
看起来对我来说,模块加载似乎是通过 import 和 export 关键字进行本地支持的。
并不完全如此。import 和 export 声明仅定义每个模块的依赖关系和接口。它们允许静态提取命名所需模块的字符串,除此之外没有其他功能。
如果是这样,我是否不需要使用额外的工具像CommonJS或RequireJS?
不。你仍然需要为ES6模块使用加载器,该加载器从import解析名称或路径或任何实际模块文件,并使用与实现相关的方法加载它们。
有许多工具或工具链可用,不同解决方案的示例包括:
webpack:将所有内容捆绑成一个大脚本 System.js:动态异步加载单个模块(类似于 require.js) 原生:Node.js和Web浏览器仍在努力支持模块加载而无需额外的库 Babel转码:您可以将ES6模块转换为AMD或CommonJS格式,并使用已知的工具(如require.js)对其进行操作。

只是为了完整理解,如果我 没有 使用像上面那样的动态模块加载器,这意味着我将受到旧的引用每个需要在我的 index.html 文件中使用的 .js 模块文件的方法(或者如果我打包和压缩,则可能是一个单独的文件)的限制吗? - atconway
@atconway 实际上,老派的<script>包含方式在模块中根本不起作用(尚未),它会尝试将它们解析为老派脚本,这将失败。你需要将模块捆绑成一个单独的脚本。 - Bergi
我应该澄清一下 - 不是<script>标签中的单个模块,而是转译后的.js ES5文件(我使用TypeScript)必须要单独引用或者使用打包版本,对吧? - atconway
1
如果我没记错的话,“ES5模块”指的是commonjs语法,因此单独引用它们是行不通的。要么将它们捆绑在一起,要么使用像require.js这样的commonjs加载器。 - Bergi

2
据我所知,ES6支持定义和导入模块的语法。实际导入所需模块的工作由基础设施完成。
现代浏览器(截至2016年)没有内置功能来支持模块加载,因此您仍然需要像SystemJS这样的工具来进行实际加载。

1
浏览器是否会支持模块加载? - Chris Nevill

1
ES6 JavaScript文件本质上被视为模块。如果您在.js文件中定义了任何内容,它只能在该文件中可见(局部范围)。export的作用是将定义为export的类/变量公开,使其对外可见,然后可以将其导入到另一个模块中。还有其他定义模块的方法,例如使用Commonjs或AMD等。如果您想动态地懒加载模块,则需要使用模块加载器。例如,Systemjs是这样一个动态模块加载器。当请求时,它会动态地从服务器获取物理模块文件,并防止多次加载同一文件。在过去的SPA应用程序中,必须在一开始加载所有内容才能使其工作。现在,有了动态模块加载器,我们只需拥有执行所需工作的文件即可。希望这能帮助到您。

https://github.com/systemjs/systemjs


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接