javascript框架设计读书笔记之模块加载系统(5)


Module.prototype._compile = function() {
126     var module = this         
127     // 如果该模块已经编译过,则直接返回module.exports
128     if (module.status === STATUS.COMPILED) {
129       return module.exports
130     }
133     //  1. the module file is 404.
134     //  2. the module file is not written with valid module format.
135     //  3. other error cases.
136     // 这里是处理一些异常情况,此时直接返回null
137     if (module.status < STATUS.SAVED && !hasModifiers(module)) {
138       return null
139     }
140     // 更改模块状态为COMPILING,表示模块正在编译
141     module.status = STATUS.COMPILING
142
143     // 模块内部使用,是一个方法,用来获取其他模块提供(称之为子模块)的接口,同步操作
144     function require(id) {
145         // 根据id解析模块的路径
146         var uri = resolve(id, module.uri)
147         // 从模块缓存中获取模块(注意,其实这里子模块作为主模块的依赖项是已经被下载下来的)
148         var child = cachedModules[uri]
149
150         // Just return null when uri is invalid.
151         // 如果child为空,只能表示参数填写出错导致uri不正确,那么直接返回null
152         if (!child) {
153           return null
154         }
155
156         // Avoids circular calls.
157         // 如果子模块的状态为STATUS.COMPILING,直接返回child.exports,避免因为循环依赖反复编译模块
158         if (child.status === STATUS.COMPILING) {
159           return child.exports
160         }
161         // 指向初始化时调用当前模块的模块。根据该属性,可以得到模块初始化时的Call Stack.
162         child.parent = module
163         // 返回编译过的child的module.exports
164         return child._compile()
165     }
166     // 模块内部使用,用来异步加载模块,并在加载完成后执行指定回调。
167     require.async = function(ids, callback) {
168       module._use(ids, callback)
169     }
170     // 使用模块系统内部的路径解析机制来解析并返回模块路径。该函数不会加载模块,只返回解析后的绝对路径。
171     require.resolve = function(id) {
172       return resolve(id, module.uri)
173     }
174     // 通过该属性,可以查看到模块系统加载过的所有模块。
175     // 在某些情况下,如果需要重新加载某个模块,可以得到该模块的 uri, 然后通过 delete require.cache[uri] 来将其信息删除掉。这样下次          使用时,就会重新获取。
176     require.cache = cachedModules
177
178     // require是一个方法,用来获取其他模块提供的接口。
179     module.require = require
180     // exports是一个对象,用来向外提供模块接口。
181     module.exports = {}
182     var factory = module.factory
183
184     // factory 为函数时,表示模块的构造方法。执行该方法,可以得到模块向外提供的接口。
185     if (util.isFunction(factory)) {
186       compileStack.push(module)
187       runInModuleContext(factory, module)
188       compileStack.pop()
189     }
190     // factory 为对象、字符串等非函数类型时,表示模块的接口就是该对象、字符串等值。
191     // 如:define({ "foo": "bar" });
192     // 如:define('I am a template. My name is {{name}}.');
193     else if (factory !== undefined) {
194       module.exports = factory
195     }
196
197     // 更改模块状态为COMPILED,表示模块已编译
198     module.status = STATUS.COMPILED
199     // 执行模块接口修改,通过seajs.modify()
200     execModifiers(module)
201     return module.exports
202   }

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgsyjw.html