第一篇: 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文件的邏輯!