2014-07-03 89 views
5

我一直在readingaboutes6 module loaders我只是不太明白它是如何工作的,我希望有人能够启发我。es6模块如何加载工作

在实际的工作流程链接上面,他们有这样的

System.import('app/app').then(function(app) { 
    // app is now the Module object with exports as getters 
}); 

与没有问题的例子 - 我明白了。但后来我看到这样的东西

var $ = require('jquery'); 

并得到真正困惑。如果在这次调用时jquery还没有传输到浏览器会发生什么?线程是否旋转?浏览器是否在幕后解析你的脚本并将它改造成像RequireJs这样的回调?它是可配置的?有特定的限制吗?

有人可以给我一个破败?

+1

您看到的第二件事是“CommonJS模块加载”,而不是ES6 afaik。它确实[在require.js中不工作(很好)](http://requirejs.org/docs/api.html#cjsmodule) – Bergi

+0

@Bergi它在require.js中正常工作,而我不喜欢它我当前项目中的某些页面使用requirejs和commonjs风格。 Requirejs扫描脚本中的commonjs表达式并将其重写为amd格式,因此它仍然使用回调函数。但是,除非我错了,否则es6建议不会使用回调 - 因此我很困惑。 –

+0

是的,除了最简单的情况外,扫描脚本并不适用于所有情况。你能链接你所说的ES6提案的部分吗? 'System.import'显然使用回调。 – Bergi

回答

4

ES6模块加载器将获取源代码,确定依赖关系,并在执行模块之前等待这些依赖项已经加载。所以在require执行的时候,依赖关系已经在那里等待执行了。

当通过ES6模块加载器加载CommonJS时,我们依赖从源静态解析出require语句,并且只有在需要加载的时候才执行源代码。

这样我们可以在浏览器中动态加载CommonJS。循环引用的处理方式与在Node中处理的方式相同。

解析出require的正则表达式实际上非常可靠和快速,同时考虑了注释和周围的令牌。 SystemJS使用的一个请参见https://github.com/systemjs/systemjs/blob/master/lib/extension-cjs.js#L10

这种方法还有一个限制,那就是动态条件CommonJS需要像if (condition) require('some' + 'name')那样检测不到。尽管使CommonJS在浏览器中表现为完全异步模块格式,但这是一个必要的成本。

+1

我写了这个问题后的一段时间,我们得到了[关于es6模块的这篇文章](http://www.2ality.com/2014/09/es6-modules-final.html)。它直接违背了你所说的一些东西(例如,正则表达式解析,循环依赖关系的工作方式以及动态需求的可用性)。看起来我的一些混淆至少是模块和模块加载器是独立的规格,只有前者是完整的。 –

+2

的ES6模块加载器有两种方式来解释模块:通过被称为“实例化”钩 1. ES6模块 2.旧模块格式 我们所用的传统模块格式建立到ES6模块加载器。 你是对的 - ES6模块加载也有其自己的循环引用样式,这与CommonJS不同。 将CommonJS支持写入加载器时,可以允许完全CommonJS样式的循环引用支持。 就规格而言,模块加载器类行为本身在ES6规范中,单独的规范是什么是确切的环境挂钩。 – guybedford