我正在尝试回答,
何时使用导入/导出以及何时使用 require()/ module.exports ?但是当我尝试挖掘时,它似乎变得复杂起来。
这是我的理解
import语句用于导入由另一个模块导出的绑定。不管您是否声明导入模块,都处于严格模式。除非嵌入式脚本具有type =“ module”,否则无法在嵌入式脚本中使用import语句。
问题1 :通常如何与babel或webpack或浏览器一起使用?
在探索的过程中,我遇到了CommonJ,requireJ,异步模块定义(AMD)之类的东西
问题2 :我对了解时间轴感兴趣,因为这些东西在javascript中是如何演变的?
答案 0 :(得分:4)
这一般如何与babel或webpack或浏览器一起使用?
Babel和Webpack遵循ES规范,并将import
/ export
语句转换为一个文件。由于它们还支持require
语法,因此通常将import
语句转换为require()
调用,将export
语句转换为module exports
,然后附带自定义模块的加载程序。,例如:
// A.js
export default function() { }
// B.js
import A from "./A";
A();
然后将其转换为以下require
语法:
//A.js
exports.default = function() {};
//B.js
var A = require("./A").default;
A();
然后可以将其包装为:
(function() { // prevent leaking to global scope
// emulated loader:
var modules = {};
function require(name) { return modules[name]; }
function define(name, fn) {
var module = modules[name] = { exports: {} };
fn(module, module.exports, require);
}
// The code:
define("A", function(module, exports, require) {
// A.js
exports.default = function() { };
});
define("B", function(module, exports, require) {
// B.js
var A = require("A").default;
A();
});
})();
这些东西在javascript中是如何演变的?
几年前,编写JS仅限于浏览器,并且加载多个js源的唯一方法是使用多个<script>
标签并使用全局对象交换功能。那太丑了。
然后发明了Node.js,他们需要一种更好的方式来使用模块并发明了require()
。
规范的作者看到了为此的本机语法的需要,因此引入了import
/ export
。
Babel和其他人随后写了译本。
答案 1 :(得分:2)
捆绑程序执行的Webpack如下:
Webpack将查看输入文件requires
(commomJS模块系统)或imports
(ES6模块系统)中的所有文件。然后,它通过加载程序根据文件名扩展来合并代码。 加载程序可以将各个文件转换为浏览器可以理解的代码。加载程序的一个示例是babel或sass / scss编译器。
使用加载程序转译不同的文件后,插件可以在 将生成的代码的捆绑包转换为其他内容。捆绑包只是一堆代码,一起构成了功能
在webpack的内部不会太深入,但是最重要的是:
您使用webpack,以便可以将代码拆分成多个文件,这使它们更易于维护和使用。但是,然后由客户端请求所有这些文件对于性能而言将是可怕的(许多HTTP请求开销)。因此,我们将文件捆绑为一个或几个文件,以减少这种开销。
答案 2 :(得分:0)
通常,如果您正在使用像webpack这样的打包程序,或者使用Babel进行翻译,则应该使用import / export语法编写所有现代代码。npm模块可能更喜欢require / module语法,但是您仍然可以导入它们。
还值得注意的是import()
方法,该方法返回一个承诺,该承诺应解析为异步导入的根模块。如果已配置Webpack,则可以将它们捆绑为异步模块。
在实践中,通过babel和webpack之类的工具进行的解析将退回到针对node_modules
查找的节点样式的行为,其中的标准是传输路径,而相对路径更受青睐。每个环境都提供额外的支持。
您可以在现代浏览器和当前节点中试用esm支持(此答案后面的标记后面)。行为有些不一致,但定义明确。如有疑问,请尝试并尝试。