From a335d51f665b48a57f4aca0bf218b3728091056e Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 21 Nov 2025 11:18:47 +0100 Subject: [PATCH] Adds hot reload launch config (#277123) * Adds hot reload launch config --------- Co-authored-by: Benjamin Pasero Co-authored-by: Benjamin Pasero --- .vscode/launch.json | 14 +++++---- .vscode/tasks.json | 2 +- build/npm/dirs.js | 2 +- build/tsconfig.json | 2 +- .../index-workbench.ts | 0 .../index.html | 0 .../index.ts | 0 .../package-lock.json | 0 .../package.json | 0 .../rollup-url-to-module-plugin/index.mjs | 0 .../setup-dev.ts | 3 ++ .../style.css | 0 .../tsconfig.json | 0 .../vite.config.ts | 30 +++++++++++++++++-- build/vite/workbench-electron.ts | 8 +++++ build/vite/workbench-vite-electron.html | 13 ++++++++ .../workbench-vite.html | 0 src/typings/vscode-globals-product.d.ts | 14 +++++++++ .../base/parts/ipc/electron-main/ipcMain.ts | 6 ++++ .../workbench/workbench-dev.html | 2 +- .../electron-browser/workbench/workbench.ts | 16 ++++++++-- .../windows/electron-main/windowImpl.ts | 8 ++++- 22 files changed, 104 insertions(+), 16 deletions(-) rename build/{monaco-editor-playground => vite}/index-workbench.ts (100%) rename build/{monaco-editor-playground => vite}/index.html (100%) rename build/{monaco-editor-playground => vite}/index.ts (100%) rename build/{monaco-editor-playground => vite}/package-lock.json (100%) rename build/{monaco-editor-playground => vite}/package.json (100%) rename build/{monaco-editor-playground => vite}/rollup-url-to-module-plugin/index.mjs (100%) rename build/{monaco-editor-playground => vite}/setup-dev.ts (91%) rename build/{monaco-editor-playground => vite}/style.css (100%) rename build/{monaco-editor-playground => vite}/tsconfig.json (100%) rename build/{monaco-editor-playground => vite}/vite.config.ts (84%) create mode 100644 build/vite/workbench-electron.ts create mode 100644 build/vite/workbench-vite-electron.html rename build/{monaco-editor-playground => vite}/workbench-vite.html (100%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 07407e53ab6..77adf9923af 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -282,7 +282,7 @@ // To debug observables you also need the extension "ms-vscode.debug-value-editor" "type": "chrome", "request": "launch", - "name": "Launch VS Code Internal (Dev Debug)", + "name": "Launch VS Code Internal (Hot Reload)", "windows": { "runtimeExecutable": "${workspaceFolder}/scripts/code.bat" }, @@ -298,6 +298,7 @@ "VSCODE_EXTHOST_WILL_SEND_SOCKET": null, "VSCODE_SKIP_PRELAUNCH": "1", "VSCODE_DEV_DEBUG": "1", + "DEV_WINDOW_SRC": "http://localhost:5199/build/vite/workbench-vite-electron.html", "VSCODE_DEV_DEBUG_OBSERVABLES": "1", }, "cleanUp": "wholeBrowser", @@ -322,6 +323,7 @@ "presentation": { "hidden": true, }, + "preLaunchTask": "Launch Monaco Editor Vite" }, { "type": "node", @@ -591,7 +593,7 @@ "name": "Monaco Editor - Playground", "type": "chrome", "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", "presentation": { "group": "monaco", @@ -602,7 +604,7 @@ "name": "Monaco Editor - Self Contained Diff Editor", "type": "chrome", "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", "presentation": { "group": "monaco", @@ -613,7 +615,7 @@ "name": "Monaco Editor - Workbench", "type": "chrome", "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", "presentation": { "group": "monaco", @@ -638,10 +640,10 @@ } }, { - "name": "VS Code (Debug Observables)", + "name": "VS Code (Hot Reload)", "stopAll": true, "configurations": [ - "Launch VS Code Internal (Dev Debug)", + "Launch VS Code Internal (Hot Reload)", "Attach to Main Process", "Attach to Extension Host", "Attach to Shared Process", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 96d5015f4d1..19912f49620 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -283,7 +283,7 @@ "type": "shell", "command": "npm run dev", "options": { - "cwd": "./build/monaco-editor-playground/" + "cwd": "./build/vite/" }, "isBackground": true, "problemMatcher": { diff --git a/build/npm/dirs.js b/build/npm/dirs.js index 935d8a8a529..b344c3d5959 100644 --- a/build/npm/dirs.js +++ b/build/npm/dirs.js @@ -9,7 +9,7 @@ const fs = require('fs'); const dirs = [ '', 'build', - 'build/monaco-editor-playground', + 'build/vite', 'extensions', 'extensions/configuration-editing', 'extensions/css-language-features', diff --git a/build/tsconfig.json b/build/tsconfig.json index a3cf3fbe89d..6526dfc4343 100644 --- a/build/tsconfig.json +++ b/build/tsconfig.json @@ -29,6 +29,6 @@ ], "exclude": [ "node_modules/**", - "monaco-editor-playground/**" + "vite/**" ] } diff --git a/build/monaco-editor-playground/index-workbench.ts b/build/vite/index-workbench.ts similarity index 100% rename from build/monaco-editor-playground/index-workbench.ts rename to build/vite/index-workbench.ts diff --git a/build/monaco-editor-playground/index.html b/build/vite/index.html similarity index 100% rename from build/monaco-editor-playground/index.html rename to build/vite/index.html diff --git a/build/monaco-editor-playground/index.ts b/build/vite/index.ts similarity index 100% rename from build/monaco-editor-playground/index.ts rename to build/vite/index.ts diff --git a/build/monaco-editor-playground/package-lock.json b/build/vite/package-lock.json similarity index 100% rename from build/monaco-editor-playground/package-lock.json rename to build/vite/package-lock.json diff --git a/build/monaco-editor-playground/package.json b/build/vite/package.json similarity index 100% rename from build/monaco-editor-playground/package.json rename to build/vite/package.json diff --git a/build/monaco-editor-playground/rollup-url-to-module-plugin/index.mjs b/build/vite/rollup-url-to-module-plugin/index.mjs similarity index 100% rename from build/monaco-editor-playground/rollup-url-to-module-plugin/index.mjs rename to build/vite/rollup-url-to-module-plugin/index.mjs diff --git a/build/monaco-editor-playground/setup-dev.ts b/build/vite/setup-dev.ts similarity index 91% rename from build/monaco-editor-playground/setup-dev.ts rename to build/vite/setup-dev.ts index 87505545b71..c1df4861082 100644 --- a/build/monaco-editor-playground/setup-dev.ts +++ b/build/vite/setup-dev.ts @@ -13,3 +13,6 @@ import { StandaloneWebWorkerService } from '../../src/vs/editor/standalone/brows enableHotReload(); registerSingleton(IWebWorkerService, StandaloneWebWorkerService, InstantiationType.Eager); + +globalThis._VSCODE_DISABLE_CSS_IMPORT_MAP = true; +globalThis._VSCODE_USE_RELATIVE_IMPORTS = true; diff --git a/build/monaco-editor-playground/style.css b/build/vite/style.css similarity index 100% rename from build/monaco-editor-playground/style.css rename to build/vite/style.css diff --git a/build/monaco-editor-playground/tsconfig.json b/build/vite/tsconfig.json similarity index 100% rename from build/monaco-editor-playground/tsconfig.json rename to build/vite/tsconfig.json diff --git a/build/monaco-editor-playground/vite.config.ts b/build/vite/vite.config.ts similarity index 84% rename from build/monaco-editor-playground/vite.config.ts rename to build/vite/vite.config.ts index ac1536cf578..bdb6b317ab1 100644 --- a/build/monaco-editor-playground/vite.config.ts +++ b/build/vite/vite.config.ts @@ -3,7 +3,7 @@ * 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'; /// @ts-ignore 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({ plugins: [ urlToEsmPlugin(), injectBuiltinExtensionsPlugin(), createHotClassSupport() ], + customLogger: logger, 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 server: { diff --git a/build/vite/workbench-electron.ts b/build/vite/workbench-electron.ts new file mode 100644 index 00000000000..49578ca4948 --- /dev/null +++ b/build/vite/workbench-electron.ts @@ -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'; + diff --git a/build/vite/workbench-vite-electron.html b/build/vite/workbench-vite-electron.html new file mode 100644 index 00000000000..87019c6c01a --- /dev/null +++ b/build/vite/workbench-vite-electron.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/build/monaco-editor-playground/workbench-vite.html b/build/vite/workbench-vite.html similarity index 100% rename from build/monaco-editor-playground/workbench-vite.html rename to build/vite/workbench-vite.html diff --git a/src/typings/vscode-globals-product.d.ts b/src/typings/vscode-globals-product.d.ts index 2cd632e77a0..ab169bd82d0 100644 --- a/src/typings/vscode-globals-product.d.ts +++ b/src/typings/vscode-globals-product.d.ts @@ -27,6 +27,20 @@ declare global { */ var _VSCODE_PACKAGE_JSON: Record; + /** + * 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 diff --git a/src/vs/base/parts/ipc/electron-main/ipcMain.ts b/src/vs/base/parts/ipc/electron-main/ipcMain.ts index ace40529015..0137b8924eb 100644 --- a/src/vs/base/parts/ipc/electron-main/ipcMain.ts +++ b/src/vs/base/parts/ipc/electron-main/ipcMain.ts @@ -128,6 +128,12 @@ class ValidatedIpcMain implements Event.NodeEventEmitter { 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) { onUnexpectedError(`Refused to handle ipcMain event for channel '${channel}' because of a bad origin of '${host}'.`); return false; // unexpected sender diff --git a/src/vs/code/electron-browser/workbench/workbench-dev.html b/src/vs/code/electron-browser/workbench/workbench-dev.html index 1121fc7c047..13ff778a58c 100644 --- a/src/vs/code/electron-browser/workbench/workbench-dev.html +++ b/src/vs/code/electron-browser/workbench/workbench-dev.html @@ -73,5 +73,5 @@ - + diff --git a/src/vs/code/electron-browser/workbench/workbench.ts b/src/vs/code/electron-browser/workbench/workbench.ts index 7d6c8fac0c7..da8713718c7 100644 --- a/src/vs/code/electron-browser/workbench/workbench.ts +++ b/src/vs/code/electron-browser/workbench/workbench.ts @@ -273,7 +273,7 @@ //#region Window Helpers - async function load(esModule: string, options: ILoadOptions): Promise> { + async function load(options: ILoadOptions): Promise> { // Window Configuration from Preload Script const configuration = await resolveWindowConfiguration(); @@ -296,8 +296,14 @@ // ESM Import 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) { developerDeveloperKeybindingsDisposable(); } @@ -449,6 +455,10 @@ // DEV: a blob URL that loads the CSS via a dynamic @import-rule. // DEV --------------------------------------------------------------------------------------- + if (globalThis._VSCODE_DISABLE_CSS_IMPORT_MAP) { + return; // disabled in certain development setups + } + if (Array.isArray(configuration.cssModules) && configuration.cssModules.length > 0) { performance.mark('code/willAddCssLoader'); @@ -484,7 +494,7 @@ //#endregion - const { result, configuration } = await load('vs/workbench/workbench.desktop.main', + const { result, configuration } = await load( { configureDeveloperSettings: function (windowConfig) { return { diff --git a/src/vs/platform/windows/electron-main/windowImpl.ts b/src/vs/platform/windows/electron-main/windowImpl.ts index 67c832b0ad1..7a5a81088b5 100644 --- a/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/src/vs/platform/windows/electron-main/windowImpl.ts @@ -1158,7 +1158,13 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { this.readyState = ReadyState.NAVIGATING; // 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 const wasLoaded = this.wasLoaded;