認識vscode(二)

前一篇文章簡單的介紹了一下vscode源碼結構.此次咱們來了解一下vscode的運行流程. 下一篇文章咱們則切換主題的小案例來深刻了解vscode.html

首先入口文件是main.js,這個相信大部分人都知道.那麼咱們來看看main.js的源碼.這裏至關於運行的是electron的主進程. 這裏作了一些初始化操做之後(設置schemes, 初始化一些全局配置好比編輯器工做路徑)就調用startup函數來loading vs/code/electron-main/main.tsgit

function startup(cachedDataDir, nlsConfig) {
    nlsConfig._languagePackSupport = true;

    process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfig);
    process.env['VSCODE_NODE_CACHED_DATA_DIR'] = cachedDataDir || '';

    // Load main in AMD
    perf.mark('willLoadMainBundle');
    require('./bootstrap-amd').load('vs/code/electron-main/main', () => {
        perf.mark('didLoadMainBundle');
    });
}

electron-main/main.ts 則會先初始化一些基礎服務github

private createServices(args: ParsedArgs, bufferLogService: BufferLogService): [IInstantiationService, IProcessEnvironment] {
        const services = new ServiceCollection();

        const environmentService = new EnvironmentService(args, process.execPath);
        const instanceEnvironment = this.patchEnvironment(environmentService); // Patch `process.env` with the instance's environment
        services.set(IEnvironmentService, environmentService);

        const logService = new MultiplexLogService([new ConsoleLogMainService(getLogLevel(environmentService)), bufferLogService]);
        process.once('exit', () => logService.dispose());
        services.set(ILogService, logService);

        services.set(IConfigurationService, new ConfigurationService(environmentService.settingsResource));
        services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService));
        services.set(IStateService, new SyncDescriptor(StateService));
        services.set(IRequestService, new SyncDescriptor(RequestMainService));
        services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));
        services.set(ISignService, new SyncDescriptor(SignService));

        return [new InstantiationService(services, true), instanceEnvironment];
    }

而後建立ipcServer把接力棒交給 app.tstypescript

// Startup
            await instantiationService.invokeFunction(async accessor => {
                const environmentService = accessor.get(IEnvironmentService);
                const logService = accessor.get(ILogService);
                const lifecycleMainService = accessor.get(ILifecycleMainService);
                const configurationService = accessor.get(IConfigurationService);

                const mainIpcServer = await this.doStartup(logService, environmentService, lifecycleMainService, instantiationService, true);

                bufferLogService.logger = new SpdLogService('main', environmentService.logsPath, bufferLogService.getLevel());
                once(lifecycleMainService.onWillShutdown)(() => (configurationService as ConfigurationService).dispose());

                return instantiationService.createInstance(CodeApplication, mainIpcServer, instanceEnvironment).startup();
            });

這裏咱們先了解到instantiationService. 後續咱們就常常接觸整個服務. 這能夠理解成是vscode實現DI的容器. 經過調用instantiationService.createInstance建立的對象, 對象constructor內使用裝飾器聲明瞭須要注入的service類型.則instantistionService會自動將已有的service注入bootstrap

main.tssegmentfault

return instantiationService.createInstance(CodeApplication, mainIpcServer, instanceEnvironment).startup();

app.ts constructorapp

constructor(
        private readonly mainIpcServer: Server,
        private readonly userEnv: IProcessEnvironment,
        @IInstantiationService private readonly instantiationService: IInstantiationService,
        @ILogService private readonly logService: ILogService,
        @IEnvironmentService private readonly environmentService: IEnvironmentService,
        @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
        @IConfigurationService private readonly configurationService: IConfigurationService,
        @IStateService private readonly stateService: IStateService
    ) {
        super();

        this.registerListeners();
    }

app.ts 在最後會調用window.ts 中的 open 函數來打開一個vscode窗口. 每一個window窗口都會打開workbench.html用來渲染咱們所看到的整個vscode界面.electron

private doGetUrl(config: object): string {
        return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
    }

今天的分享就到這裏. 明天咱們就來經過實現切換主題(dark mode)來深刻了解 workbench 的邏輯。async

相關文章
相關標籤/搜索