Как работает vscode

Node.js внешний интерфейс JavaScript
Как работает vscode

vscode обычно используется фронтенд-инженерами, и его реализация также основана на фронтенд-технологии. Поскольку это интерфейсная технология, мы используем основную интерфейсную технологию, чтобы достичь аналогичного vscode ide. Но до тех пор мы все еще хотим, чтобы vscode в первую очередь заключался в том, как добиться четкого обоснования. В этой статье мы берем стрижку vscode как разбежаться.

Прежде всего, vscode — это электронное приложение, а реализация окон и других функций основана на электроне, поэтому, если вы хотите разобраться в процессе запуска vscode, вам нужно сначала понять электрон.

electron

Electron выполняет логику js и рендеринг страницы на основе узла и хрома, а также предоставляет BrowserWindow для создания окон и API-интерфейс пакета electronic для выполнения некоторых функций операционной системы, таких как открытие окна выбора файла, взаимодействие процессов и т. д.

js в каждом окне BrowserWindow запускается в процессе рендеринга, а у электрона есть основной процесс, который отвечает за связь с процессом рендеринга в каждом окне.

Как показано на рисунке, основной процесс может использовать API-интерфейс nodejs и API-интерфейс, предоставленный электроном для основного процесса, а процесс рендеринга может использовать API-интерфейс браузера, API-интерфейс nodejs и API-интерфейс, предоставленный процессу рендеринга. Электрон Кроме того, процесс рендеринга также может использовать html и css для макета страницы.

Каждое окно vscode представляет собой BrowserWindow.Когда мы запускаем vscode, запускается основной процесс, а затем основной процесс запускает BrowserWindow для загрузки html окна, тем самым завершая создание окна vscode. (Последующие новые окна также создаются таким же образом, за исключением того, что процесс рендеринга уведомляет основной процесс через ipc, а затем основной процесс создает BrowserWindow, в отличие от первого запуска окна, основной процесс создает BrowserWindow напрямую. )

Процесс запуска окна VSCode

Мы знаем VSCode для прохождения на основе электрона, электронного файла JS загружается первичный процесс, который является ./OUT/Main.js VSCode основного полей Package.json объявил, мы начали смотреть на этот файл.

src/main

(Все следующие коды упрощены из исходного кода, чтобы каждый мог пояснить свои идеи)

// src/main.js
const { app } = require('electron');

app.once('ready', onReady);

async function onReady() {
    try {
        startup(xxxConfig);
    } catch (error) {
        console.error(error);
    }
}

function startUp() {
    require('./bootstrap-amd').load('vs/code/electron-main/main');
}

Как видите, ./src/main.js — это просто кусок кода начальной загрузки, который запускает выполнение записи js в готовом событии приложения. Это vs/code/electron-main/main, логика входа основного процесса.

CodeMain

// src/vs/code/electron-main/main.ts
class CodeMain {
    main(): void {
        try {
            this.startup();
        } catch (error) {
            console.error(error.message);
            app.exit(1);
        }
    }
    private async startup(): Promise<void> {
        // 创建服务
        const [
            instantiationService, 
            instanceEnvironment,
            environmentMainService,
            configurationService,
            stateMainService
        ] = this.createServices();
        
        // 初始化服务
        await this.initServices();
        
        // 启动
        await instantiationService.invokeFunction(async accessor => {
            //创建 CodeApplication 的对象,然后调用 startup
            return instantiationService.createInstance(CodeApplication).startup();
        });

    }
}

const code = new CodeMain();
code.main();

Как видите, vscode создает объект CodeMain, который является началом логики входа и классом в корне. Он создает и инициализирует некоторые службы, а затем создает объект CodeApplication.

Может быть, вы скажете, почему бы не создать объект непосредственно новым, а также вызвать xxx.invokeFunction() и xxx.createInstance()?

Это связано с тем, что vscode реализует контейнер ioc, то есть любой объект внутри контейнера может объявлять зависимости, которые затем автоматически внедряются контейнером.

Первоначально это была прямая зависимость, но, превратив ее в способ внедрения зависимостей, удалось избежать связывания.Это идея ioc (инверсия управления) или di (внедрение зависимости).

Это приложение CodeApplication является контейнером ioc.

CodeApplication

//src/vs/code/electron-main/app.ts

export class CodeApplication {

    // 依赖注入
    constructor(
        @IInstantiationService private readonly mainInstantiationService: IInstantiationService,
        @IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService
    ){
        super();
    }
    
    async startup(): Promise<void> {
        const mainProcessElectronServer = new ElectronIPCServer();
        this.openFirstWindow(mainProcessElectronServer)
    }
    
    private openFirstWindow(mainProcessElectronServer: ElectronIPCServer): ICodeWindow[] {
        this.windowsMainService.open({...});
    }
}

В CodeApplication зависимости объявляются через декораторы, а объявленные зависимости автоматически внедряются при создании экземпляра через контейнер.

Запуск запускает первое окно, которое представляет собой процесс рендеринга.Поскольку основной процесс и процесс рендеринга должны взаимодействовать через ipc, также создается экземпляр ElectronIPCServer (фактически он просто инкапсулирует ipc-связь).

Наконец, окно создается с помощью службы windowMainService.

Хотя это сложнее, методы службы и ioc могут лучше справляться со сложностью и гарантировать, что архитектура приложения не станет более итеративной и хаотичной.

Затем мы рассмотрим конкретную логику создания окна.

windowMainService

//src/vs/platform/windows/electron-main/windowsMainService.ts

export class WindowsMainService {
    
    open(openConfig): ICodeWindow[] {
       this.doOpen(openConfig);
    }
    
    doOpen(openConfig) {
        this.openInBrowserWindow();
    }
    
    openInBrowserWindow(options) {
        // 创建窗口
        this.instantiationService.createInstance(CodeWindow);
    }
}

В windowMainService, наконец, создается экземпляр CodeWindow, который является инкапсуляцией BrowserWindow, который является окном vscode. (созданный с помощью xxx.createIntance, поскольку он управляется контейнером ioc)

CodeWindow

//src/vs/platform/windows/electron-main/window.ts
import { BrowserWindow } from 'electron';

export class CodeWindow {
    constructor() {
        const options = {...};
        this._win = new BrowserWindow(options);
        this.registerListeners();
        this._win.loadURL('vs/code/electron-browser/workbench/workbench.html');
    }
}

CodeWindow — это инкапсуляция BrowserWindow от Electron, который является оконным классом vscode.

Он создает окно BrowserWindow, прослушивает ряд событий окна и, наконец, загружает html рабочей среды. Это содержимое окна vscode, которое мы обычно видим.

На данный момент мы выполнили логику запуска электрона для отображения первого окна vscode, и мы уже можем видеть интерфейс vscode.

Суммировать

vscode основан на электронах для создания окон и взаимодействия между процессами.Когда приложение запускается, оно запускает основной процесс, начинает выполнение из src/main, а затем создает объект CodeMain.

Многие службы будут инициализированы в CodeMain, а затем будет создано приложение CodeApplication, которое является реализацией ioc и глобально уникально. Созданием объектов управляет контейнер, и все объекты в нем могут быть внедрены с зависимостями.

Во-первых, экземпляр CodeWindow будет создан через службу windowMainSerice, которая является объектом окна, который является инкапсуляцией BrowserWindow электрона.

Загрузите workbench.html в окно, это интерфейс vscode, который мы видим.

Таким образом, vscode реализует создание окна и отображение интерфейса на основе электрона.Если вам интересно, вы можете обратиться к этой статье, чтобы увидеть исходный код vscode 1.59.0.Вы можете узнать много архитектурных вещей, таких как контейнер ioc Выполнять унифицированное управление объектами и управлять различными ресурсами с помощью различных служб.Этот централизованный метод управления делает архитектуру менее итеративной и хаотичной, а сложность хорошо управляемой.Кроме того, изучение исходного кода vscode также может улучшить опыт работы с электроном.мастер .