因为它已经在使用,你知道下一seajs源代码。这是我的几个问题的认识:

1、如何要求(XXX)的方法seajs实现模块加载

2。为什么他们需要预装

三.为什么需要构建工具

4,建造前后的代码有什么不同,为什么这么做

如何要求(XXX)对问题1的方法:seajs实现模块加载

代码逻辑进行了比较,对源代码的理解在文章的结尾。在这里,模块加载的逻辑是用简单的方法进行梳理的。

1,从seajs.use方法入门,开始加载使用模块。

2, use to the module at this time the mod cache must not exist.Seajs creates a new mod to give some initial state.

三.执行mod.load方法

4。一堆逻辑后,就去seajs.request方法和要求的模块文件。在模块加载完成后,定义方法执行。

5,定义方法分析提取模块的依赖模块并保存它。缓存工厂但不执行。

6,模块的依赖模块再次加载,如果它继续依赖于模块,它将继续加载,直到所有相关模块都加载完毕。

7。在加载完所有模块之后,回调函数。使用方法的执行

8,模块的内部逻辑从回调开始。

问题2:为什么需要预装

我们看到seajs.use实际执行回调方法只有在所有依赖的模块已经加载。据了解,之前的业务逻辑代码的执行,所有的相关模块的代码必须预装第一。那么为什么它是一个逻辑必须预装一次

答案是在引用其他模块方法的逻辑代码中执行需求方法的方法:

var =要求(id);

这种语法决定了mod的获取是一个同步执行过程。如果模块代码不预装之前,它只能通过异步加载回调方法的实施,使整个seajs执行逻辑是完全不同的。因为你不理解模块的逻辑序列,将很难控制。

问题3:为什么需要构建工具

可以看出,在构建之前,每个依赖模块都是单独加载的,这会产生太多的模块请求,这对页面的加载性能是不利的,构建工具本质上是解决模块合并加载的问题。

问题4:建造前后的代码有什么不同,为什么会这样做

构建工具是做什么的我们说它本质上是为了解决代码合并加载的问题,所以它所做的只是将每个模块文件合并成一个文件

当然不是。测试,如果您只是将几个模块文件合并到一个文件中,您将发现根本无法执行该文件。

原因是定义方法的实现。

seajs引入到工厂参数只在定义方法时,定义模块是尊敬。看看里面的定义方法,当有来电ID(姑且等同于模块的URL),通过getcurrentscript()来获取URL路径模块文件的方法正在执行,然后走这条路的钥匙模块本身一起缓存cachedmods。这里的关键点是,模块的缓存机制在整个seajs实际上是依赖于每个模块的URL进行缓存的核心价值,需要(ID)的方法是,在最后的分析中,重点对URL的要求(ID)的方法。,说到底,是找到相应的模块,通过URL的cachedmods这个关键关键。不可重复和不可犯了一个错误,或者模块的通信混乱。如果A,B和C模块文件简单的合并成一个目标文件的x,getcurrentscript()只能得到X,这三个模块的关键值的路径不可区分,执行一定是错的。

所以如果你想合并几个模块文件,您必须为每个模块做一个明确的URI,定义的方法必须被传递到ID参数。当我通过,seajs将ID的URL缓存键值。

如果ID和工厂,这是定义(ID,工厂),然后稀释每股收益=未定义,定义方法将执行parsedependencies(factory.tostring())提取方法依赖于工厂内部的模块,后续会去解析模块路径逻辑内线各模块分装,失去的时间的复合加载的意义。

所以合并荷载,定义方法必须正确地传递到三参数id,依赖,和工厂被正确地执行。

seajs所谓CMD模块定义的方法是提倡你写工厂模块只在某个阶段,与其他两个参数在以后的代码建设阶段产生的。这解释了为什么这两个参数是必要的施工后。

至于为什么只有出厂时是经过促进模块的定义,我认为这主要是因为ID和该参数的引入方面,这是非常容易出错,维护不方便,该工具可以提高效率,保证参数的正确性。

附录:对seajs主要代码逻辑的理解。

描述:sea.js 2.3.0版本的源代码

1。看看定义方法做了什么

module.define =功能(ID,DEPS,工厂)

当定义法、三参数的支持。其中ID,该是可选的。工厂必须的代码是通过以下逻辑控制:


但事实上,该是必要的,因为seajs必须知道哪些模块每个模块的依赖,或不能执行负载。

因此,当工厂是一个功能和依赖不主动介绍,我们需要使用parsedependencies分析工厂的依赖模块。


parsedependencies的方法主要是从XXX(XXX)都需要提取功能体与一个正则表达式,这是所有模块的功能取决于。


方法本身并不复杂,但正则表达式并不简单:

在该分析模块定义存储在缓存中的:


注意,我们会发现定义方法纯粹是一个分析模块,一个存储模块,并且没有执行模块。

2。真正的执行模块是需要的方法。



简而言之,需求方法是基于id在定义的存储模块缓存中找到的相应模块,并执行它来获得模块定义返回的方式。


这整个大步骤,有一个非常重要的步骤,这是必要的:

module.get(require.resolve(ID))。

当需要为一个模块,该模块是第一个发现的module.get方法扮演了这一角色。


如果没有在cachedmods,创建一个新的模块和缓存cachedmods:


定义与rquire方法似乎并不复杂,seajs逻辑主要模块加载有点复杂。

3,要seajs房入口的使用方法:


通过使用方法,IDS从这里开始加载和执行模块。


你可以看到负载的关键点是在mod.load方法。

加载方法代码有点长,主要的逻辑是确定mod的当前状态是否被加载或加载。


在模块的舒适功能中,我们可以看到状态默认值是0。


所以没有新的模块已经加载,和这里所有的是:mod.status = status.loading状态设置为负载,负载和后续执行逻辑。

下面是依赖URL的采集模块


mod.resolve方法:


在本质上,这module.resolve方法是将相对路径配置的路径,别名,所以没有编码为绝对路径。

更新模块加载状态。


加载模块逻辑:


它的主要m.fetch方法,和其他逻辑跳过这里。


你可以看到,seajs.request最终将执行模块文件的加载:


当所有的从属模块被加载,执行MOD的OnLoad方法


这里是mod.onload()方法


在这一点上,seajs的核心逻辑是几乎所有见过。供参考,没有一个地方能够理解或表达不准确的地方,欢迎一起讨论。

以上是本文的全部内容,希望大家能喜欢。