第一篇: vscode源码分析【一】从源码运行vscode
第二篇:vscode源码分析【二】程序的启动逻辑,第一个窗口是如何建立的
第三篇:vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第四篇:vscode源码分析【四】程序启动的逻辑,最初建立的服务
第五篇:vscode源码分析【五】事件分发机制
第六篇:vscode源码分析【六】服务实例化和单例的实现
第七篇:vscode源码分析【七】主进程启动消息通讯服务
先复习一下!
在第一节中,咱们提到:
app.ts(src\vs\code\electron-main\app.ts)的openFirstWindow方法中,
有个WindowsMainServicehtml
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService); // TODO@Joao: unfold this //... windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!hasCliArgs && args['unity-launch']), diffMode: args.diff, noRecentEntry, waitMarkerFileURI, initialStartup: true });
这个WindowsMainService
(接口文件:src\vs\platform\windows\electron-main\windows.ts)
(实例文件:src\vs\code\electron-main\windows.ts)
接口和实例的关系,是在这里作成的(407行):windows
services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv]));
实例的open方法最关键的一句话是:app
const usedWindows = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyToRestore, emptyToOpen, fileInputs, foldersToAdd);
在doOpen方法里调用了:this.openInBrowserWindow,并把这个窗口保存到usedWindows里去了;
(若是已经有打开的窗口,那么就用现成的窗口打开新的内容)electron
usedWindows.push(this.openInBrowserWindow({ userEnv: openConfig.userEnv, cli: openConfig.cli, initialStartup: openConfig.initialStartup, fileInputs: fileInputsForWindow, remoteAuthority, forceNewWindow: true, forceNewTabbedWindow: openConfig.forceNewTabbedWindow, emptyWindowBackupInfo }));
咱们接下来去看看openInBrowserWindow作了什么
其中最关键的一句:函数
window = this.instantiationService.createInstance(CodeWindow, { state, extensionDevelopmentPath: configuration.extensionDevelopmentPath, isExtensionTestHost: !!configuration.extensionTestsPath });
CodeWindow的构造函数里,调用了createBrowserWindow方法,在这个方法里建立了咱们的Electron的BrowserWindow
(src\vs\code\electron-main\window.ts)源码分析
this._win = new BrowserWindow(options);
好!窗口建立出来了,那么窗口中的内容呢?按道理来讲应该加载一个页面用于展示UI的呀?
复习结束,下面是新的内容
咱们接着去看openInBrowserWindow方法的后面的内容,发现有这么一句:post
if (window.isReady) { this.lifecycleService.unload(window, UnloadReason.LOAD).then(veto => { if (!veto) { this.doOpenInBrowserWindow(window!, configuration, options); } }); } else { this.doOpenInBrowserWindow(window, configuration, options); }
在doOpenInBrowserWindow里,调用了性能
window.load(configuration);
OK!咱们再回到CodeWindow的类型里去,看看load方法作了什么
咱们看到了这一句:ui
this._win.loadURL(this.getUrl(configuration));
他们在getUrl方法里作了一堆跟URL一点关系也没有的事情
好比说:设置窗口的缩放级别,设置全屏、设置窗口ID之类的
作完这些无关的事情,有跳进了另外一个函数:this
let configUrl = this.doGetUrl(config); return configUrl;
在这个doGetUrl里只有一句话:
return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
这个require.toUrl方法采用通用的模块ID路径转化规则,将模块ID字符解析成URL路径;
注意:file:///协议开头的URL路径;
至此,这个窗口总算显示出了一个画面!
这个页面body里并无任何东西;只加载了一个js文件
<script src="workbench.js"></script>
后面咱们再继续聊这个js文件的逻辑!