Adds hot reload launch config (#277123)

* Adds hot reload launch config

---------

Co-authored-by: Benjamin Pasero <benjamin.pasero@gmail.com>
Co-authored-by: Benjamin Pasero <benjamin.pasero@microsoft.com>
This commit is contained in:
Henning Dieterichs
2025-11-21 11:18:47 +01:00
committed by GitHub
parent 76fb5a42b1
commit a335d51f66
22 changed files with 104 additions and 16 deletions

14
.vscode/launch.json vendored
View File

@@ -282,7 +282,7 @@
// To debug observables you also need the extension "ms-vscode.debug-value-editor" // To debug observables you also need the extension "ms-vscode.debug-value-editor"
"type": "chrome", "type": "chrome",
"request": "launch", "request": "launch",
"name": "Launch VS Code Internal (Dev Debug)", "name": "Launch VS Code Internal (Hot Reload)",
"windows": { "windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.bat" "runtimeExecutable": "${workspaceFolder}/scripts/code.bat"
}, },
@@ -298,6 +298,7 @@
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null, "VSCODE_EXTHOST_WILL_SEND_SOCKET": null,
"VSCODE_SKIP_PRELAUNCH": "1", "VSCODE_SKIP_PRELAUNCH": "1",
"VSCODE_DEV_DEBUG": "1", "VSCODE_DEV_DEBUG": "1",
"DEV_WINDOW_SRC": "http://localhost:5199/build/vite/workbench-vite-electron.html",
"VSCODE_DEV_DEBUG_OBSERVABLES": "1", "VSCODE_DEV_DEBUG_OBSERVABLES": "1",
}, },
"cleanUp": "wholeBrowser", "cleanUp": "wholeBrowser",
@@ -322,6 +323,7 @@
"presentation": { "presentation": {
"hidden": true, "hidden": true,
}, },
"preLaunchTask": "Launch Monaco Editor Vite"
}, },
{ {
"type": "node", "type": "node",
@@ -591,7 +593,7 @@
"name": "Monaco Editor - Playground", "name": "Monaco Editor - Playground",
"type": "chrome", "type": "chrome",
"request": "launch", "request": "launch",
"url": "https://microsoft.github.io/monaco-editor/playground.html?source=http%3A%2F%2Flocalhost%3A5199%2Fbuild%2Fmonaco-editor-playground%2Findex.ts%3Fesm#example-creating-the-editor-hello-world", "url": "https://microsoft.github.io/monaco-editor/playground.html?source=http%3A%2F%2Flocalhost%3A5199%2Fbuild%2Fvite%2Findex.ts%3Fesm#example-creating-the-editor-hello-world",
"preLaunchTask": "Launch Monaco Editor Vite", "preLaunchTask": "Launch Monaco Editor Vite",
"presentation": { "presentation": {
"group": "monaco", "group": "monaco",
@@ -602,7 +604,7 @@
"name": "Monaco Editor - Self Contained Diff Editor", "name": "Monaco Editor - Self Contained Diff Editor",
"type": "chrome", "type": "chrome",
"request": "launch", "request": "launch",
"url": "http://localhost:5199/build/monaco-editor-playground/index.html", "url": "http://localhost:5199/build/vite/index.html",
"preLaunchTask": "Launch Monaco Editor Vite", "preLaunchTask": "Launch Monaco Editor Vite",
"presentation": { "presentation": {
"group": "monaco", "group": "monaco",
@@ -613,7 +615,7 @@
"name": "Monaco Editor - Workbench", "name": "Monaco Editor - Workbench",
"type": "chrome", "type": "chrome",
"request": "launch", "request": "launch",
"url": "http://localhost:5199/build/monaco-editor-playground/workbench-vite.html", "url": "http://localhost:5199/build/vite/workbench-vite.html",
"preLaunchTask": "Launch Monaco Editor Vite", "preLaunchTask": "Launch Monaco Editor Vite",
"presentation": { "presentation": {
"group": "monaco", "group": "monaco",
@@ -638,10 +640,10 @@
} }
}, },
{ {
"name": "VS Code (Debug Observables)", "name": "VS Code (Hot Reload)",
"stopAll": true, "stopAll": true,
"configurations": [ "configurations": [
"Launch VS Code Internal (Dev Debug)", "Launch VS Code Internal (Hot Reload)",
"Attach to Main Process", "Attach to Main Process",
"Attach to Extension Host", "Attach to Extension Host",
"Attach to Shared Process", "Attach to Shared Process",

2
.vscode/tasks.json vendored
View File

@@ -283,7 +283,7 @@
"type": "shell", "type": "shell",
"command": "npm run dev", "command": "npm run dev",
"options": { "options": {
"cwd": "./build/monaco-editor-playground/" "cwd": "./build/vite/"
}, },
"isBackground": true, "isBackground": true,
"problemMatcher": { "problemMatcher": {

View File

@@ -9,7 +9,7 @@ const fs = require('fs');
const dirs = [ const dirs = [
'', '',
'build', 'build',
'build/monaco-editor-playground', 'build/vite',
'extensions', 'extensions',
'extensions/configuration-editing', 'extensions/configuration-editing',
'extensions/css-language-features', 'extensions/css-language-features',

View File

@@ -29,6 +29,6 @@
], ],
"exclude": [ "exclude": [
"node_modules/**", "node_modules/**",
"monaco-editor-playground/**" "vite/**"
] ]
} }

View File

@@ -13,3 +13,6 @@ import { StandaloneWebWorkerService } from '../../src/vs/editor/standalone/brows
enableHotReload(); enableHotReload();
registerSingleton(IWebWorkerService, StandaloneWebWorkerService, InstantiationType.Eager); registerSingleton(IWebWorkerService, StandaloneWebWorkerService, InstantiationType.Eager);
globalThis._VSCODE_DISABLE_CSS_IMPORT_MAP = true;
globalThis._VSCODE_USE_RELATIVE_IMPORTS = true;

View File

@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { defineConfig, Plugin } from 'vite'; import { createLogger, defineConfig, Plugin } from 'vite';
import path, { join } from 'path'; import path, { join } from 'path';
/// @ts-ignore /// @ts-ignore
import { urlToEsmPlugin } from './rollup-url-to-module-plugin/index.mjs'; import { urlToEsmPlugin } from './rollup-url-to-module-plugin/index.mjs';
@@ -114,14 +114,40 @@ if (import.meta.hot) {
}; };
} }
const logger = createLogger();
const loggerWarn = logger.warn;
logger.warn = (msg, options) => {
// amdX and the baseUrl code cannot be analyzed by vite.
// However, they are not needed, so it is okay to silence the warning.
if (msg.indexOf('vs/amdX.ts') !== -1) {
return;
}
if (msg.indexOf('await import(new URL(`vs/workbench/workbench.desktop.main.js`, baseUrl).href)') !== -1) {
return;
}
// See https://github.com/microsoft/vscode/issues/278153
if (msg.indexOf('marked.esm.js.map') !== -1 || msg.indexOf('purify.es.mjs.map') !== -1) {
return;
}
loggerWarn(msg, options);
};
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
urlToEsmPlugin(), urlToEsmPlugin(),
injectBuiltinExtensionsPlugin(), injectBuiltinExtensionsPlugin(),
createHotClassSupport() createHotClassSupport()
], ],
customLogger: logger,
esbuild: { esbuild: {
target: 'es6', // to fix property initialization issues, not needed when loading monaco-editor from npm package tsconfigRaw: {
compilerOptions: {
experimentalDecorators: true,
}
}
}, },
root: '../..', // To support /out/... paths root: '../..', // To support /out/... paths
server: { server: {

View File

@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import './setup-dev';
import '../../src/vs/code/electron-browser/workbench/workbench';

View File

@@ -0,0 +1,13 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body aria-label="">
</body>
<!-- Startup (do not modify order of script tags!) -->
<script type="module" src="./workbench-electron.ts"></script>
</html>

View File

@@ -27,6 +27,20 @@ declare global {
*/ */
var _VSCODE_PACKAGE_JSON: Record<string, any>; var _VSCODE_PACKAGE_JSON: Record<string, any>;
/**
* Used to disable CSS import map loading during development. Needed
* when a bundler is used that loads the css directly.
* @deprecated Avoid using this variable.
*/
var _VSCODE_DISABLE_CSS_IMPORT_MAP: boolean | undefined;
/**
* If this variable is set, and the source code references another module
* via import, the (relative) module should be referenced (instead of the
* JS module in the out folder).
* @deprecated Avoid using this variable.
*/
var _VSCODE_USE_RELATIVE_IMPORTS: boolean | undefined;
} }
// fake export to make global work // fake export to make global work

View File

@@ -128,6 +128,12 @@ class ValidatedIpcMain implements Event.NodeEventEmitter {
return false; // unexpected URL return false; // unexpected URL
} }
if (process.env.VSCODE_DEV) {
if (url === process.env.DEV_WINDOW_SRC && (host === 'localhost' || host.startsWith('localhost:'))) {
return true; // development support where the window is served from localhost
}
}
if (host !== VSCODE_AUTHORITY) { if (host !== VSCODE_AUTHORITY) {
onUnexpectedError(`Refused to handle ipcMain event for channel '${channel}' because of a bad origin of '${host}'.`); onUnexpectedError(`Refused to handle ipcMain event for channel '${channel}' because of a bad origin of '${host}'.`);
return false; // unexpected sender return false; // unexpected sender

View File

@@ -73,5 +73,5 @@
</body> </body>
<!-- Startup (do not modify order of script tags!) --> <!-- Startup (do not modify order of script tags!) -->
<script src="./workbench.js"></script> <script src="./workbench.js" type="module"></script>
</html> </html>

View File

@@ -273,7 +273,7 @@
//#region Window Helpers //#region Window Helpers
async function load<M, T extends ISandboxConfiguration>(esModule: string, options: ILoadOptions<T>): Promise<ILoadResult<M, T>> { async function load<M, T extends ISandboxConfiguration>(options: ILoadOptions<T>): Promise<ILoadResult<M, T>> {
// Window Configuration from Preload Script // Window Configuration from Preload Script
const configuration = await resolveWindowConfiguration<T>(); const configuration = await resolveWindowConfiguration<T>();
@@ -296,8 +296,14 @@
// ESM Import // ESM Import
try { try {
const result = await import(new URL(`${esModule}.js`, baseUrl).href); let workbenchUrl: string;
if (!!safeProcess.env['VSCODE_DEV'] && globalThis._VSCODE_USE_RELATIVE_IMPORTS) {
workbenchUrl = '../../../workbench/workbench.desktop.main.js'; // for dev purposes only
} else {
workbenchUrl = new URL(`vs/workbench/workbench.desktop.main.js`, baseUrl).href;
}
const result = await import(workbenchUrl);
if (developerDeveloperKeybindingsDisposable && removeDeveloperKeybindingsAfterLoad) { if (developerDeveloperKeybindingsDisposable && removeDeveloperKeybindingsAfterLoad) {
developerDeveloperKeybindingsDisposable(); developerDeveloperKeybindingsDisposable();
} }
@@ -449,6 +455,10 @@
// DEV: a blob URL that loads the CSS via a dynamic @import-rule. // DEV: a blob URL that loads the CSS via a dynamic @import-rule.
// DEV --------------------------------------------------------------------------------------- // DEV ---------------------------------------------------------------------------------------
if (globalThis._VSCODE_DISABLE_CSS_IMPORT_MAP) {
return; // disabled in certain development setups
}
if (Array.isArray(configuration.cssModules) && configuration.cssModules.length > 0) { if (Array.isArray(configuration.cssModules) && configuration.cssModules.length > 0) {
performance.mark('code/willAddCssLoader'); performance.mark('code/willAddCssLoader');
@@ -484,7 +494,7 @@
//#endregion //#endregion
const { result, configuration } = await load<IDesktopMain, INativeWindowConfiguration>('vs/workbench/workbench.desktop.main', const { result, configuration } = await load<IDesktopMain, INativeWindowConfiguration>(
{ {
configureDeveloperSettings: function (windowConfig) { configureDeveloperSettings: function (windowConfig) {
return { return {

View File

@@ -1158,7 +1158,13 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
this.readyState = ReadyState.NAVIGATING; this.readyState = ReadyState.NAVIGATING;
// Load URL // Load URL
this._win.loadURL(FileAccess.asBrowserUri(`vs/code/electron-browser/workbench/workbench${this.environmentMainService.isBuilt ? '' : '-dev'}.html`).toString(true)); let windowUrl: string;
if (process.env.VSCODE_DEV && process.env.VSCODE_DEV_SERVER_URL) {
windowUrl = process.env.VSCODE_DEV_SERVER_URL; // support URL override for development
} else {
windowUrl = FileAccess.asBrowserUri(`vs/code/electron-browser/workbench/workbench${this.environmentMainService.isBuilt ? '' : '-dev'}.html`).toString(true);
}
this._win.loadURL(windowUrl);
// Remember that we did load // Remember that we did load
const wasLoaded = this.wasLoaded; const wasLoaded = this.wasLoaded;