项目代码运行原理
初始化项目会实例化以下几个类 Runtime Runtime.Module Runtime.Extension
Last updated
初始化项目会实例化以下几个类 Runtime Runtime.Module Runtime.Extension
Last updated
以下以devtools_app.html 页面为例分析dev-tools初始化流程
项目是访问静态网页重点加载runtime.js、devtools_app.js
代码内容仅仅包含(静态方法)Runtime.startApplication('devtools_app')
1、优先从全局全局描述符(allDescriptors)遍历出来name => 模块描述的对象
2、如果找不到当前当前应用的描述对象(applicationDescriptor),则加载“应用名”.json,加载方式采用xmlrequest 请求当前目录下的xxx.json
3、解析devtools_app.json并赋值给descriptor ,找到extends扩展名称的,有则while一直递归加载所有依赖(例如依赖),并合并到 applicationDescriptor的modules,如果没有则直接下一步(这一步加载 devtools_app extends联调的json文件)
4、遍历modules,加载根据name(当前目录的文件夹名)/module.json,注意加载所需的文件,如果描述符中type=autostart则放到核心模块列表中最终形成一个模块列表,模块信息对象如下(这一步是把整个devtools_app 依赖的模块文件对应的json文件加载并组织了整个模块列表)
5、new runtime的实例
6、上一步已经将所有模块以及模块下的扩展都已经建立好对象关联关系,还没有任何加载对应脚本的代码,接下来优先加载核心模块(例如["bindings", "common", "components", "console_counters", "dom_extension", "extensions", "host", "main", "persistence", "platform", "product_registry", "protocol", "sdk", "browser_sdk", "services", "text_utils", "ui", "workspace", "emulation", "inspector_main", "mobile_throttling"]),先从this._modulesMap中调用name to modules的实例方法_loadPromise 这个方法会加载需要的模块。并从runtime实例中的_modulesMap属性去取当前模块的信息(其实每一个模块都是加载模块的js和css,资源路径是:根/moduleName/resourcesName,模块本身只是信息存储),加载之前会优先把该模块所有依赖模块放到promise中 然后promise.all(依赖模块).then(this._loadResources.bind(this)) .then(this._loadScripts.bind(this)) 然后每一个模块本身又_loadPromise 去加载依赖的依赖(加载之前有一个判断返回_pendingLoadPromise,如果这个模块已经在加载队列则不需要循环调用) 注: _loadScripts 比较特别,会判断是否是远程模块,来自(2)中于shell.json中的type, 最终执行回来的代码片段
7、到此dev-tools Runtime实例已经建立完成,它主要完成runtime上挂载modules实例,modules 挂载 extensions 实例,但这里没有说明到底那步开始正式执行devtools的组织和渲染
其实在6的步骤中加载了一个 main的核心模块,这个模块加载完成成后立即执行Main.Main(); 然后执行_appStartedPromise, 将fulfil 返回回来并且 startApplication 最后一步执行_appStartedPromiseCallback()