From 4c1b0e9ff18424364eee9eb9d4bdb8041068c713 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 6 Aug 2024 16:32:43 +0200 Subject: [PATCH] esm - reduce diff (#224919) * esm - reduce diff * . * . * . * . * . --- .eslintrc.json | 2 +- build/gulpfile.vscode.js | 1 - src/bootstrap-amd.js | 31 ++- src/bootstrap-fork.js | 4 +- src/bootstrap-node.js | 86 ++++++ src/bootstrap-window.js | 55 ++-- src/bootstrap.js | 141 ---------- src/cli.js | 4 +- src/main.js | 4 +- src/server-main.js | 2 +- src/tsconfig.json | 1 - src/vs/amdX.ts | 28 +- src/vs/base/browser/defaultWorkerFactory.ts | 1 - src/vs/base/common/platform.ts | 1 - .../processExplorer/processExplorer-dev.html | 3 +- .../workbench/workbench-dev.html | 3 +- src/vs/nls.ts | 2 - .../node/nativeModules.integrationTest.ts | 27 +- .../extensionSignatureVerificationService.ts | 10 +- .../issue/electron-main/issueMainService.ts | 1 - .../issue/electron-main/processMainService.ts | 1 - src/vs/platform/sign/browser/signService.ts | 10 +- .../sign/common/abstractSignService.ts | 6 +- src/vs/platform/sign/node/signService.ts | 3 +- .../electron-main/windowsMainService.ts | 1 - .../node/remoteExtensionHostAgentServer.ts | 2 +- .../codeEditor/test/node/autoindent.test.ts | 3 +- .../test/node/language-configuration.json | 250 ++++++++++++++++++ .../electron-sandbox/issueReporter-dev.html | 3 +- .../issue/electron-sandbox/issueReporter.html | 2 +- .../browser/webWorkerExtensionHost.ts | 7 +- .../worker/webWorkerExtensionHostIframe.html | 25 +- test/unit/browser/index.js | 1 - test/unit/electron/renderer.js | 5 +- test/unit/node/index.js | 36 +-- 35 files changed, 470 insertions(+), 292 deletions(-) delete mode 100644 src/bootstrap.js create mode 100644 src/vs/workbench/contrib/codeEditor/test/node/language-configuration.json diff --git a/.eslintrc.json b/.eslintrc.json index d7f317c85b9f0..8dafc03b0873b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1033,7 +1033,7 @@ "restrictions": [] }, { - "target": "src/{bootstrap-amd.js,bootstrap-fork.js,bootstrap-node.js,bootstrap-window.js,bootstrap.js,cli.js,main.js,server-cli.js,server-main.js}", + "target": "src/{bootstrap-amd.js,bootstrap-fork.js,bootstrap-node.js,bootstrap-window.js,cli.js,main.js,server-cli.js,server-main.js}", "restrictions": [] } ] diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 9a3c2dd12f32d..34d5d79fbe694 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -80,7 +80,6 @@ const vscodeResources = [ // be inlined into the target window file in this order // and they depend on each other in this way. const windowBootstrapFiles = [ - 'out-build/bootstrap.js', 'out-build/vs/loader.js', 'out-build/bootstrap-window.js' ]; diff --git a/src/bootstrap-amd.js b/src/bootstrap-amd.js index 96b1d468ba08a..c228faccfed1d 100644 --- a/src/bootstrap-amd.js +++ b/src/bootstrap-amd.js @@ -19,17 +19,33 @@ const isESM = false; // import * as fs from 'fs'; // import { fileURLToPath } from 'url'; // import { createRequire, register } from 'node:module'; -// if (process.env['ELECTRON_RUN_AS_NODE'] || process.versions['electron']) { -// register('./loader-original-fs.mjs', import.meta.url); -// } // import { product, pkg } from './bootstrap-meta.js'; -// import * as bootstrap from './bootstrap.js'; +// import * as bootstrapNode from './bootstrap-node.js'; // import * as performance from './vs/base/common/performance.js'; // // const require = createRequire(import.meta.url); // const isESM = true; // const module = { exports: {} }; // const __dirname = path.dirname(fileURLToPath(import.meta.url)); +// +// // Install a hook to module resolution to map 'fs' to 'original-fs' +// if (process.env['ELECTRON_RUN_AS_NODE'] || process.versions['electron']) { +// const jsCode = ` +// export async function resolve(specifier, context, nextResolve) { +// if (specifier === 'fs') { +// return { +// format: 'builtin', +// shortCircuit: true, +// url: 'node:original-fs' +// }; +// } + +// // Defer to the next hook in the chain, which would be the +// // Node.js default resolve if this is the last user-specified loader. +// return nextResolve(specifier, context); +// }`; +// register(`data:text/javascript;base64,${Buffer.from(jsCode).toString('base64')}`, import.meta.url); +// } // ESM-uncomment-end // Store the node.js require function in a variable @@ -67,7 +83,7 @@ globalThis._VSCODE_PACKAGE_JSON = require('./bootstrap-meta').pkg; globalThis._VSCODE_FILE_ROOT = __dirname; // ESM-comment-begin -const bootstrap = require('./bootstrap'); +const bootstrapNode = require('./bootstrap-node'); const performance = require(`./vs/base/common/performance`); const fs = require('fs'); // ESM-comment-end @@ -109,7 +125,6 @@ async function doSetupNLS() { messagesFile = nlsConfig.defaultMessagesFile; } - // VSCODE_GLOBALS: NLS globalThis._VSCODE_NLS_LANGUAGE = nlsConfig?.resolvedLanguage; } catch (e) { console.error(`Error reading VSCODE_NLS_CONFIG from environment: ${e}`); @@ -124,7 +139,6 @@ async function doSetupNLS() { } try { - // VSCODE_GLOBALS: NLS globalThis._VSCODE_NLS_MESSAGES = JSON.parse((await fs.promises.readFile(messagesFile)).toString()); } catch (error) { console.error(`Error reading NLS messages file ${messagesFile}: ${error}`); @@ -141,7 +155,6 @@ async function doSetupNLS() { // Fallback to the default message file to ensure english translation at least if (nlsConfig?.defaultMessagesFile && nlsConfig.defaultMessagesFile !== messagesFile) { try { - // VSCODE_GLOBALS: NLS globalThis._VSCODE_NLS_MESSAGES = JSON.parse((await fs.promises.readFile(nlsConfig.defaultMessagesFile)).toString()); } catch (error) { console.error(`Error reading default NLS messages file ${nlsConfig.defaultMessagesFile}: ${error}`); @@ -186,7 +199,7 @@ if (isESM) { const loader = require('./vs/loader'); loader.config({ - baseUrl: bootstrap.fileUriFromPath(__dirname, { isWindows: process.platform === 'win32' }), + baseUrl: bootstrapNode.fileUriFromPath(__dirname, { isWindows: process.platform === 'win32' }), catchError: true, nodeRequire, amdModulesPattern: /^vs\//, diff --git a/src/bootstrap-fork.js b/src/bootstrap-fork.js index a95cbf53589d5..009fe3e7e2d4e 100644 --- a/src/bootstrap-fork.js +++ b/src/bootstrap-fork.js @@ -8,13 +8,11 @@ // ESM-comment-begin const performance = require('./vs/base/common/performance'); -const bootstrap = require('./bootstrap'); const bootstrapNode = require('./bootstrap-node'); const bootstrapAmd = require('./bootstrap-amd'); // ESM-comment-end // ESM-uncomment-begin // import * as performance from './vs/base/common/performance.js'; -// import * as bootstrap from './bootstrap.js'; // import * as bootstrapNode from './bootstrap-node.js'; // import * as bootstrapAmd from './bootstrap-amd.js'; // ESM-uncomment-end @@ -28,7 +26,7 @@ configureCrashReporter(); bootstrapNode.removeGlobalNodeModuleLookupPaths(); // Enable ASAR in our forked processes -bootstrap.enableASARSupport(); +bootstrapNode.enableASARSupport(); if (process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH']) { bootstrapNode.injectNodeModuleLookupPath(process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH']); diff --git a/src/bootstrap-node.js b/src/bootstrap-node.js index 7c00e7e047ec5..5183526e1d529 100644 --- a/src/bootstrap-node.js +++ b/src/bootstrap-node.js @@ -9,6 +9,7 @@ // ESM-comment-begin const path = require('path'); const fs = require('fs'); +const Module = require('module'); const isESM = false; // ESM-comment-end @@ -19,11 +20,30 @@ const isESM = false; // import { createRequire } from 'node:module'; // // const require = createRequire(import.meta.url); +// const Module = require('module'); // const isESM = true; // const module = { exports: {} }; // const __dirname = path.dirname(fileURLToPath(import.meta.url)); // ESM-uncomment-end +// increase number of stack frames(from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) +Error.stackTraceLimit = 100; + +if (!process.env['VSCODE_HANDLES_SIGPIPE']) { + // Workaround for Electron not installing a handler to ignore SIGPIPE + // (https://github.com/electron/electron/issues/13254) + let didLogAboutSIGPIPE = false; + process.on('SIGPIPE', () => { + // See https://github.com/microsoft/vscode-remote-release/issues/6543 + // In certain situations, the console itself can be in a broken pipe state + // so logging SIGPIPE to the console will cause an infinite async loop + if (!didLogAboutSIGPIPE) { + didLogAboutSIGPIPE = true; + console.error(new Error(`Unexpected SIGPIPE`)); + } + }); +} + // Setup current working directory in all our node & electron processes // - Windows: call `process.chdir()` to always set application folder as cwd // - all OS: store the `process.cwd()` inside `VSCODE_CWD` for consistent lookups @@ -177,8 +197,74 @@ module.exports.configurePortable = function (product) { }; }; +/** + * Helper to enable ASAR support. + */ +module.exports.enableASARSupport = function () { + const NODE_MODULES_PATH = path.join(__dirname, '../node_modules'); + const NODE_MODULES_ASAR_PATH = `${NODE_MODULES_PATH}.asar`; + + // @ts-ignore + const originalResolveLookupPaths = Module._resolveLookupPaths; + + // @ts-ignore + Module._resolveLookupPaths = function (request, parent) { + const paths = originalResolveLookupPaths(request, parent); + if (Array.isArray(paths)) { + for (let i = 0, len = paths.length; i < len; i++) { + if (paths[i] === NODE_MODULES_PATH) { + paths.splice(i, 0, NODE_MODULES_ASAR_PATH); + break; + } + } + } + + return paths; + }; +}; + +/** + * Helper to convert a file path to a URI. + * + * TODO@bpasero check for removal once ESM has landed. + * + * @param {string} path + * @param {{ isWindows?: boolean, scheme?: string, fallbackAuthority?: string }} config + * @returns {string} + */ +module.exports.fileUriFromPath = function (path, config) { + + // Since we are building a URI, we normalize any backslash + // to slashes and we ensure that the path begins with a '/'. + let pathName = path.replace(/\\/g, '/'); + if (pathName.length > 0 && pathName.charAt(0) !== '/') { + pathName = `/${pathName}`; + } + + /** @type {string} */ + let uri; + + // Windows: in order to support UNC paths (which start with '//') + // that have their own authority, we do not use the provided authority + // but rather preserve it. + if (config.isWindows && pathName.startsWith('//')) { + uri = encodeURI(`${config.scheme || 'file'}:${pathName}`); + } + + // Otherwise we optionally add the provided authority if specified + else { + uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`); + } + + return uri.replace(/#/g, '%23'); +}; + +//#endregion + // ESM-uncomment-begin // export const injectNodeModuleLookupPath = module.exports.injectNodeModuleLookupPath; // export const removeGlobalNodeModuleLookupPaths = module.exports.removeGlobalNodeModuleLookupPaths; // export const configurePortable = module.exports.configurePortable; +// export const enableASARSupport = module.exports.enableASARSupport; +// export const fileUriFromPath = module.exports.fileUriFromPath; // ESM-uncomment-end diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js index ccc437c304f40..ee06b29d53c4b 100644 --- a/src/bootstrap-window.js +++ b/src/bootstrap-window.js @@ -13,7 +13,7 @@ * @typedef {any} LoaderConfig */ -/* eslint-disable no-restricted-globals, */ +/* eslint-disable no-restricted-globals */ // ESM-comment-begin const isESM = false; @@ -22,24 +22,16 @@ const isESM = false; // const isESM = true; // ESM-uncomment-end -// Simple module style to support node.js and browser environments (function (factory) { - - // Node.js - if (typeof exports === 'object') { - module.exports = factory(); - } - - // Browser - else { - // @ts-ignore - globalThis.MonacoBootstrapWindow = factory(); - } + // @ts-ignore + globalThis.MonacoBootstrapWindow = factory(); }(function () { - const bootstrapLib = bootstrap(); const preloadGlobals = sandboxGlobals(); const safeProcess = preloadGlobals.process; + // increase number of stack frames(from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) + Error.stackTraceLimit = 100; + /** * @param {string[]} modulePaths * @param {(result: unknown, configuration: ISandboxConfiguration) => Promise | undefined} resultCallback @@ -90,7 +82,6 @@ const isESM = false; developerDeveloperKeybindingsDisposable = registerDeveloperKeybindings(disallowReloadKeybinding); } - // VSCODE_GLOBALS: NLS globalThis._VSCODE_NLS_MESSAGES = configuration.nls.messages; globalThis._VSCODE_NLS_LANGUAGE = configuration.nls.language; let language = configuration.nls.language || 'en'; @@ -178,7 +169,7 @@ const isESM = false; /** @type {LoaderConfig} */ const loaderConfig = { - baseUrl: `${bootstrapLib.fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out`, + baseUrl: `${fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out`, preferScriptTags: true }; @@ -317,11 +308,35 @@ const isESM = false; } /** - * @return {{ fileUriFromPath: (path: string, config: { isWindows?: boolean, scheme?: string, fallbackAuthority?: string }) => string; }} + * @param {string} path + * @param {{ isWindows?: boolean, scheme?: string, fallbackAuthority?: string }} config + * @returns {string} */ - function bootstrap() { - // @ts-ignore (defined in bootstrap.js) - return window.MonacoBootstrap; + function fileUriFromPath(path, config) { + + // Since we are building a URI, we normalize any backslash + // to slashes and we ensure that the path begins with a '/'. + let pathName = path.replace(/\\/g, '/'); + if (pathName.length > 0 && pathName.charAt(0) !== '/') { + pathName = `/${pathName}`; + } + + /** @type {string} */ + let uri; + + // Windows: in order to support UNC paths (which start with '//') + // that have their own authority, we do not use the provided authority + // but rather preserve it. + if (config.isWindows && pathName.startsWith('//')) { + uri = encodeURI(`${config.scheme || 'file'}:${pathName}`); + } + + // Otherwise we optionally add the provided authority if specified + else { + uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`); + } + + return uri.replace(/#/g, '%23'); } /** diff --git a/src/bootstrap.js b/src/bootstrap.js deleted file mode 100644 index 63e7501a69689..0000000000000 --- a/src/bootstrap.js +++ /dev/null @@ -1,141 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -//@ts-check -'use strict'; - -// TODO@bpasero this file can no longer be used from a non-node.js context and thus should -// move into bootstrap-node.js and remaining usages (if any) in browser context be replaced. - -// ESM-uncomment-begin -// import * as path from 'path'; -// import { createRequire } from 'node:module'; -// import { fileURLToPath } from 'url'; -// -// const require = createRequire(import.meta.url); -// const module = { exports: {} }; -// const __dirname = path.dirname(fileURLToPath(import.meta.url)); -// ESM-uncomment-end - -// Simple module style to support node.js and browser environments -(function (factory) { - - // Node.js - if (typeof module === 'object' && typeof module.exports === 'object') { - module.exports = factory(); - } - - // Browser - else { - // @ts-ignore - globalThis.MonacoBootstrap = factory(); - } -}(function () { - const Module = typeof require === 'function' ? require('module') : undefined; - const path = typeof require === 'function' ? require('path') : undefined; - - //#region global bootstrapping - - // increase number of stack frames(from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) - Error.stackTraceLimit = 100; - - if (typeof process !== 'undefined' && !process.env['VSCODE_HANDLES_SIGPIPE']) { - // Workaround for Electron not installing a handler to ignore SIGPIPE - // (https://github.com/electron/electron/issues/13254) - let didLogAboutSIGPIPE = false; - process.on('SIGPIPE', () => { - // See https://github.com/microsoft/vscode-remote-release/issues/6543 - // We would normally install a SIGPIPE listener in bootstrap.js - // But in certain situations, the console itself can be in a broken pipe state - // so logging SIGPIPE to the console will cause an infinite async loop - if (!didLogAboutSIGPIPE) { - didLogAboutSIGPIPE = true; - console.error(new Error(`Unexpected SIGPIPE`)); - } - }); - } - - //#endregion - - - //#region Add support for using node_modules.asar - - function enableASARSupport() { - if (!path || !Module || typeof process === 'undefined') { - console.warn('enableASARSupport() is only available in node.js environments'); - return; - } - - const NODE_MODULES_PATH = path.join(__dirname, '../node_modules'); - const NODE_MODULES_ASAR_PATH = `${NODE_MODULES_PATH}.asar`; - - // @ts-ignore - const originalResolveLookupPaths = Module._resolveLookupPaths; - - // @ts-ignore - Module._resolveLookupPaths = function (request, parent) { - const paths = originalResolveLookupPaths(request, parent); - if (Array.isArray(paths)) { - for (let i = 0, len = paths.length; i < len; i++) { - if (paths[i] === NODE_MODULES_PATH) { - paths.splice(i, 0, NODE_MODULES_ASAR_PATH); - break; - } - } - } - - return paths; - }; - } - - //#endregion - - - //#region URI helpers - - /** - * @param {string} path - * @param {{ isWindows?: boolean, scheme?: string, fallbackAuthority?: string }} config - * @returns {string} - */ - function fileUriFromPath(path, config) { - - // Since we are building a URI, we normalize any backslash - // to slashes and we ensure that the path begins with a '/'. - let pathName = path.replace(/\\/g, '/'); - if (pathName.length > 0 && pathName.charAt(0) !== '/') { - pathName = `/${pathName}`; - } - - /** @type {string} */ - let uri; - - // Windows: in order to support UNC paths (which start with '//') - // that have their own authority, we do not use the provided authority - // but rather preserve it. - if (config.isWindows && pathName.startsWith('//')) { - uri = encodeURI(`${config.scheme || 'file'}:${pathName}`); - } - - // Otherwise we optionally add the provided authority if specified - else { - uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`); - } - - return uri.replace(/#/g, '%23'); - } - - //#endregion - - return { - enableASARSupport, - fileUriFromPath - }; -})); - -// ESM-uncomment-begin -// export const enableASARSupport = module.exports.enableASARSupport; -// export const fileUriFromPath = module.exports.fileUriFromPath; -// ESM-uncomment-end diff --git a/src/cli.js b/src/cli.js index 6d2a313332267..56521564c320b 100644 --- a/src/cli.js +++ b/src/cli.js @@ -14,7 +14,6 @@ delete process.env['VSCODE_CWD']; // ESM-comment-begin -const bootstrap = require('./bootstrap'); const bootstrapNode = require('./bootstrap-node'); const bootstrapAmd = require('./bootstrap-amd'); const { resolveNLSConfiguration } = require('./vs/base/node/nls'); @@ -23,7 +22,6 @@ const product = require('./bootstrap-meta').product; // ESM-uncomment-begin // import * as path from 'path'; // import { fileURLToPath } from 'url'; -// import * as bootstrap from './bootstrap.js'; // import * as bootstrapNode from './bootstrap-node.js'; // import * as bootstrapAmd from './bootstrap-amd.js'; // import { resolveNLSConfiguration } from './vs/base/node/nls.js'; @@ -43,7 +41,7 @@ async function start() { bootstrapNode.configurePortable(product); // Enable ASAR support - bootstrap.enableASARSupport(); + bootstrapNode.enableASARSupport(); // Signal processes that we got launched as CLI process.env['VSCODE_CLI'] = '1'; diff --git a/src/main.js b/src/main.js index 94c05171e0f5d..804bb89cc0152 100644 --- a/src/main.js +++ b/src/main.js @@ -15,7 +15,6 @@ const path = require('path'); const fs = require('original-fs'); const os = require('os'); -const bootstrap = require('./bootstrap'); const bootstrapNode = require('./bootstrap-node'); const bootstrapAmd = require('./bootstrap-amd'); const { getUserDataPath } = require(`./vs/platform/environment/node/userDataPath`); @@ -30,7 +29,6 @@ const { app, protocol, crashReporter, Menu, contentTracing } = require('electron // import * as path from 'path'; // import * as fs from 'original-fs'; // import * as os from 'os'; -// import * as bootstrap from './bootstrap.js'; // import * as bootstrapNode from './bootstrap-node.js'; // import * as bootstrapAmd from './bootstrap-amd.js'; // import { fileURLToPath } from 'url'; @@ -51,7 +49,7 @@ perf.mark('code/didStartMain'); const portable = bootstrapNode.configurePortable(product); // Enable ASAR support -bootstrap.enableASARSupport(); +bootstrapNode.enableASARSupport(); // ESM-comment-begin const minimist = require('minimist'); // !!! IMPORTANT: MUST come after bootstrap#enableASARSupport diff --git a/src/server-main.js b/src/server-main.js index f1fad8f0b51b0..141101518b97a 100644 --- a/src/server-main.js +++ b/src/server-main.js @@ -285,7 +285,7 @@ function loadCode(nlsConfiguration) { process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfiguration); // required for `bootstrap-amd` to pick up NLS messages // See https://github.com/microsoft/vscode-remote-release/issues/6543 - // We would normally install a SIGPIPE listener in bootstrap.js + // We would normally install a SIGPIPE listener in bootstrap-node.js // But in certain situations, the console itself can be in a broken pipe state // so logging SIGPIPE to the console will cause an infinite async loop process.env['VSCODE_HANDLES_SIGPIPE'] = 'true'; diff --git a/src/tsconfig.json b/src/tsconfig.json index b8d6d1e1fceba..1e897747fe8f4 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -25,7 +25,6 @@ ] }, "include": [ - "./bootstrap.js", "./bootstrap-amd.js", "./bootstrap-fork.js", "./bootstrap-meta.js", diff --git a/src/vs/amdX.ts b/src/vs/amdX.ts index 14ac018b299de..8433284d976ab 100644 --- a/src/vs/amdX.ts +++ b/src/vs/amdX.ts @@ -129,25 +129,23 @@ class AMDModuleImporter { }); } - private _workerLoadScript(scriptSrc: string): Promise { - return new Promise((resolve, reject) => { - try { - if (this._amdPolicy) { - scriptSrc = this._amdPolicy.createScriptURL(scriptSrc) as any as string; - } - importScripts(scriptSrc); - resolve(this._defineCalls.pop()); - } catch (err) { - reject(err); - } - }); + private async _workerLoadScript(scriptSrc: string): Promise { + if (this._amdPolicy) { + scriptSrc = this._amdPolicy.createScriptURL(scriptSrc) as any as string; + } + if (isESM) { + await import(scriptSrc); + } else { + importScripts(scriptSrc); + } + return this._defineCalls.pop(); } private async _nodeJSLoadScript(scriptSrc: string): Promise { try { - const fs = globalThis._VSCODE_NODE_MODULES['fs']; - const vm = globalThis._VSCODE_NODE_MODULES['vm']; - const module = globalThis._VSCODE_NODE_MODULES['module']; + const fs = (globalThis as any)._VSCODE_NODE_MODULES['fs']; + const vm = (globalThis as any)._VSCODE_NODE_MODULES['vm']; + const module = (globalThis as any)._VSCODE_NODE_MODULES['module']; const filePath = URI.parse(scriptSrc).fsPath; const content = fs.readFileSync(filePath).toString(); diff --git a/src/vs/base/browser/defaultWorkerFactory.ts b/src/vs/base/browser/defaultWorkerFactory.ts index 8f077b399aba0..0861a3cb75134 100644 --- a/src/vs/base/browser/defaultWorkerFactory.ts +++ b/src/vs/base/browser/defaultWorkerFactory.ts @@ -79,7 +79,6 @@ export function getWorkerBootstrapUrl(scriptPath: string, label: string): string const blob = new Blob([[ `/*${label}*/`, `globalThis.MonacoEnvironment = { baseUrl: '${workerBaseUrl}' };`, - // VSCODE_GLOBALS: NLS `globalThis._VSCODE_NLS_MESSAGES = ${JSON.stringify(globalThis._VSCODE_NLS_MESSAGES)};`, `globalThis._VSCODE_NLS_LANGUAGE = ${JSON.stringify(globalThis._VSCODE_NLS_LANGUAGE)};`, `const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });`, diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index d931e64dfa9e6..d15362501a69e 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -103,7 +103,6 @@ else if (typeof navigator === 'object' && !isElectronRenderer) { _isLinux = _userAgent.indexOf('Linux') >= 0; _isMobile = _userAgent?.indexOf('Mobi') >= 0; _isWeb = true; - // VSCODE_GLOBALS: NLS _language = globalThis._VSCODE_NLS_LANGUAGE || LANGUAGE_DEFAULT; _locale = navigator.language.toLowerCase(); _platformLocale = _locale; diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorer-dev.html b/src/vs/code/electron-sandbox/processExplorer/processExplorer-dev.html index 55f2c0fe81ca2..dd0548c22c19d 100644 --- a/src/vs/code/electron-sandbox/processExplorer/processExplorer-dev.html +++ b/src/vs/code/electron-sandbox/processExplorer/processExplorer-dev.html @@ -35,8 +35,7 @@ - - + diff --git a/src/vs/code/electron-sandbox/workbench/workbench-dev.html b/src/vs/code/electron-sandbox/workbench/workbench-dev.html index a92bea242a491..b1be2b7527cee 100644 --- a/src/vs/code/electron-sandbox/workbench/workbench-dev.html +++ b/src/vs/code/electron-sandbox/workbench/workbench-dev.html @@ -68,8 +68,7 @@ - - + diff --git a/src/vs/nls.ts b/src/vs/nls.ts index 5a546325fc7a2..8303d8a32e295 100644 --- a/src/vs/nls.ts +++ b/src/vs/nls.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// VSCODE_GLOBALS: NLS const isPseudo = globalThis._VSCODE_NLS_LANGUAGE === 'pseudo' || (typeof document !== 'undefined' && document.location && document.location.hash.indexOf('pseudo=true') >= 0); export interface ILocalizeInfo { @@ -87,7 +86,6 @@ export function localize(data: ILocalizeInfo | string /* | number when built */, * depending on the target context. */ function lookupMessage(index: number, fallback: string | null): string { - // VSCODE_GLOBALS: NLS const message = globalThis._VSCODE_NLS_MESSAGES?.[index]; if (typeof message !== 'string') { if (typeof fallback === 'string') { diff --git a/src/vs/platform/environment/test/node/nativeModules.integrationTest.ts b/src/vs/platform/environment/test/node/nativeModules.integrationTest.ts index d2997c2d22b9f..fb0033b2adaa0 100644 --- a/src/vs/platform/environment/test/node/nativeModules.integrationTest.ts +++ b/src/vs/platform/environment/test/node/nativeModules.integrationTest.ts @@ -118,21 +118,18 @@ flakySuite('Native Modules (all platforms)', () => { assert.ok(typeof result === 'string' || typeof result === 'undefined', testErrorMessage('@vscode/windows-registry')); }); - test('@vscode/windows-ca-certs', async () => { - // @ts-ignore we do not directly depend on this module anymore - // but indirectly from our dependency to `@vscode/proxy-agent` - // we still want to ensure this module can work properly. - const windowsCerts = await import('@vscode/windows-ca-certs'); - const store = new windowsCerts.Crypt32(); - assert.ok(windowsCerts, testErrorMessage('@vscode/windows-ca-certs')); - let certCount = 0; - try { - while (store.next()) { - certCount++; + test('@vscode/proxy-agent', async () => { + const proxyAgent = await import('@vscode/proxy-agent'); + // This call will load `@vscode/proxy-agent` which is a native module that we want to test on Windows + const windowsCerts = await proxyAgent.loadSystemCertificates({ + log: { + trace: () => { }, + debug: () => { }, + info: () => { }, + warn: () => { }, + error: () => { } } - } finally { - store.done(); - } - assert(certCount > 0); + }); + assert.ok(windowsCerts.length > 0, testErrorMessage('@vscode/proxy-agent')); }); }); diff --git a/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts b/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts index cedabb0c12618..8d1c7fb867980 100644 --- a/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts +++ b/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { importAMDNodeModule } from 'vs/amdX'; import { getErrorMessage } from 'vs/base/common/errors'; import { IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { TargetPlatform } from 'vs/platform/extensions/common/extensions'; @@ -95,14 +96,7 @@ export class ExtensionSignatureVerificationService implements IExtensionSignatur private vsceSign(): Promise { if (!this.moduleLoadingPromise) { - this.moduleLoadingPromise = new Promise( - (resolve, reject) => require( - ['@vscode/vsce-sign'], - async (obj) => { - const instance = obj; - - return resolve(instance); - }, reject)); + this.moduleLoadingPromise = importAMDNodeModule('@vscode/vsce-sign', 'src/main.js'); } return this.moduleLoadingPromise; diff --git a/src/vs/platform/issue/electron-main/issueMainService.ts b/src/vs/platform/issue/electron-main/issueMainService.ts index 2b42d690c91c8..1aea4ead9b94e 100644 --- a/src/vs/platform/issue/electron-main/issueMainService.ts +++ b/src/vs/platform/issue/electron-main/issueMainService.ts @@ -83,7 +83,6 @@ export class IssueMainService implements IIssueMainService { }, product, nls: { - // VSCODE_GLOBALS: NLS messages: globalThis._VSCODE_NLS_MESSAGES, language: globalThis._VSCODE_NLS_LANGUAGE } diff --git a/src/vs/platform/issue/electron-main/processMainService.ts b/src/vs/platform/issue/electron-main/processMainService.ts index 76da45d897cf9..e6002ae0192f9 100644 --- a/src/vs/platform/issue/electron-main/processMainService.ts +++ b/src/vs/platform/issue/electron-main/processMainService.ts @@ -155,7 +155,6 @@ export class ProcessMainService implements IProcessMainService { data, product, nls: { - // VSCODE_GLOBALS: NLS messages: globalThis._VSCODE_NLS_MESSAGES, language: globalThis._VSCODE_NLS_LANGUAGE } diff --git a/src/vs/platform/sign/browser/signService.ts b/src/vs/platform/sign/browser/signService.ts index a9d699bf3b297..b6b08ebf466b1 100644 --- a/src/vs/platform/sign/browser/signService.ts +++ b/src/vs/platform/sign/browser/signService.ts @@ -3,8 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { importAMDNodeModule, resolveAmdNodeModulePath } from 'vs/amdX'; import { WindowIntervalTimer } from 'vs/base/browser/dom'; import { mainWindow } from 'vs/base/browser/window'; +import { isESM } from 'vs/base/common/amd'; import { memoize } from 'vs/base/common/decorators'; import { FileAccess } from 'vs/base/common/network'; import { IProductService } from 'vs/platform/product/common/productService'; @@ -62,7 +64,7 @@ export class SignService extends AbstractSignService implements ISignService { let [wasm] = await Promise.all([ this.getWasmBytes(), new Promise((resolve, reject) => { - require(['vsda'], resolve, reject); + importAMDNodeModule('vsda', 'rust/web/vsda.js').then(() => resolve(), reject); // todo@connor4312: there seems to be a bug(?) in vscode-loader with // require() not resolving in web once the script loads, so check manually @@ -74,7 +76,6 @@ export class SignService extends AbstractSignService implements ISignService { }).finally(() => checkInterval.dispose()), ]); - const keyBytes = new TextEncoder().encode(this.productService.serverLicense?.join('\n') || ''); for (let i = 0; i + STEP_SIZE < keyBytes.length; i += STEP_SIZE) { const key = await crypto.subtle.importKey('raw', keyBytes.slice(i + IV_SIZE, i + IV_SIZE + KEY_SIZE), { name: 'AES-CBC' }, false, ['decrypt']); @@ -87,7 +88,10 @@ export class SignService extends AbstractSignService implements ISignService { } private async getWasmBytes(): Promise { - const response = await fetch(FileAccess.asBrowserUri('vsda/../vsda_bg.wasm').toString(true)); + const url = isESM + ? resolveAmdNodeModulePath('vsda', 'rust/web/vsda_bg.wasm') + : FileAccess.asBrowserUri('vsda/../vsda_bg.wasm').toString(true); + const response = await fetch(url); if (!response.ok) { throw new Error('error loading vsda'); } diff --git a/src/vs/platform/sign/common/abstractSignService.ts b/src/vs/platform/sign/common/abstractSignService.ts index 6f7c91ba95828..838dde9151865 100644 --- a/src/vs/platform/sign/common/abstractSignService.ts +++ b/src/vs/platform/sign/common/abstractSignService.ts @@ -36,7 +36,7 @@ export abstract class AbstractSignService implements ISignService { }; } } catch (e) { - // ignore errors silently + console.error(e); } return { id: '', data: value }; } @@ -54,7 +54,7 @@ export abstract class AbstractSignService implements ISignService { try { return (validator.validate(value) === 'ok'); } catch (e) { - // ignore errors silently + console.error(e); return false; } finally { validator.dispose?.(); @@ -65,7 +65,7 @@ export abstract class AbstractSignService implements ISignService { try { return await this.signValue(value); } catch (e) { - // ignore errors silently + console.error(e); } return value; } diff --git a/src/vs/platform/sign/node/signService.ts b/src/vs/platform/sign/node/signService.ts index d07ba9cfbe940..1a2023d6ad145 100644 --- a/src/vs/platform/sign/node/signService.ts +++ b/src/vs/platform/sign/node/signService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { importAMDNodeModule } from 'vs/amdX'; import { AbstractSignService, IVsdaValidator } from 'vs/platform/sign/common/abstractSignService'; import { ISignService } from 'vs/platform/sign/common/sign'; @@ -29,6 +30,6 @@ export class SignService extends AbstractSignService implements ISignService { } private vsda(): Promise { - return new Promise((resolve, reject) => require(['vsda'], resolve, reject)); + return importAMDNodeModule('vsda', 'index.js'); } } diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 070c7ae05d384..5e6279486fc77 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -1445,7 +1445,6 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic userEnv: { ...this.initialUserEnv, ...options.userEnv }, nls: { - // VSCODE_GLOBALS: NLS messages: globalThis._VSCODE_NLS_MESSAGES, language: globalThis._VSCODE_NLS_LANGUAGE }, diff --git a/src/vs/server/node/remoteExtensionHostAgentServer.ts b/src/vs/server/node/remoteExtensionHostAgentServer.ts index 29aa95e5683fe..d9bb0122f648e 100644 --- a/src/vs/server/node/remoteExtensionHostAgentServer.ts +++ b/src/vs/server/node/remoteExtensionHostAgentServer.ts @@ -696,7 +696,7 @@ export async function createServer(address: string | net.AddressInfo | null, arg let didLogAboutSIGPIPE = false; process.on('SIGPIPE', () => { // See https://github.com/microsoft/vscode-remote-release/issues/6543 - // We would normally install a SIGPIPE listener in bootstrap.js + // We would normally install a SIGPIPE listener in bootstrap-node.js // But in certain situations, the console itself can be in a broken pipe state // so logging SIGPIPE to the console will cause an infinite async loop if (!didLogAboutSIGPIPE) { diff --git a/src/vs/workbench/contrib/codeEditor/test/node/autoindent.test.ts b/src/vs/workbench/contrib/codeEditor/test/node/autoindent.test.ts index fe3632fb8d070..1bd9688ea69a2 100644 --- a/src/vs/workbench/contrib/codeEditor/test/node/autoindent.test.ts +++ b/src/vs/workbench/contrib/codeEditor/test/node/autoindent.test.ts @@ -23,6 +23,7 @@ import { EncodedTokenizationResult, IState, ITokenizationSupport, TokenizationRe import { NullState } from 'vs/editor/common/languages/nullTokenize'; import { MetadataConsts, StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; import { ITextModel } from 'vs/editor/common/model'; +import { FileAccess } from 'vs/base/common/network'; function getIRange(range: IRange): IRange { return { @@ -56,7 +57,7 @@ function registerLanguageConfiguration(instantiationService: TestInstantiationSe let configPath: string; switch (languageId) { case LanguageId.TypeScript: - configPath = path.join('extensions', 'typescript-basics', 'language-configuration.json'); + configPath = FileAccess.asFileUri('vs/workbench/contrib/codeEditor/test/node/language-configuration.json').fsPath; break; default: throw new Error('Unknown languageId'); diff --git a/src/vs/workbench/contrib/codeEditor/test/node/language-configuration.json b/src/vs/workbench/contrib/codeEditor/test/node/language-configuration.json new file mode 100644 index 0000000000000..25a2368573841 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/test/node/language-configuration.json @@ -0,0 +1,250 @@ +{ + // Note that this file should stay in sync with 'javascript-language-basics/javascript-language-configuration.json' + "comments": { + "lineComment": "//", + "blockComment": [ + "/*", + "*/" + ] + }, + "brackets": [ + [ + "${", + "}" + ], + [ + "{", + "}" + ], + [ + "[", + "]" + ], + [ + "(", + ")" + ] + ], + "autoClosingPairs": [ + { + "open": "{", + "close": "}" + }, + { + "open": "[", + "close": "]" + }, + { + "open": "(", + "close": ")" + }, + { + "open": "'", + "close": "'", + "notIn": [ + "string", + "comment" + ] + }, + { + "open": "\"", + "close": "\"", + "notIn": [ + "string" + ] + }, + { + "open": "`", + "close": "`", + "notIn": [ + "string", + "comment" + ] + }, + { + "open": "/**", + "close": " */", + "notIn": [ + "string" + ] + } + ], + "surroundingPairs": [ + [ + "{", + "}" + ], + [ + "[", + "]" + ], + [ + "(", + ")" + ], + [ + "'", + "'" + ], + [ + "\"", + "\"" + ], + [ + "`", + "`" + ], + [ + "<", + ">" + ] + ], + "colorizedBracketPairs": [ + [ + "(", + ")" + ], + [ + "[", + "]" + ], + [ + "{", + "}" + ], + [ + "<", + ">" + ] + ], + "autoCloseBefore": ";:.,=}])>` \n\t", + "folding": { + "markers": { + "start": "^\\s*//\\s*#?region\\b", + "end": "^\\s*//\\s*#?endregion\\b" + } + }, + "wordPattern": { + "pattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\@\\~\\!\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>/\\?\\s]+)", + }, + "indentationRules": { + "decreaseIndentPattern": { + "pattern": "^\\s*[\\}\\]\\)].*$" + }, + "increaseIndentPattern": { + "pattern": "^.*(\\{[^}]*|\\([^)]*|\\[[^\\]]*)$" + }, + // e.g. * ...| or */| or *-----*/| + "unIndentedLinePattern": { + "pattern": "^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$|^(\\t|[ ])*[ ]\\*/\\s*$|^(\\t|[ ])*\\*([ ]([^\\*]|\\*(?!/))*)?$" + }, + "indentNextLinePattern": { + "pattern": "^((.*=>\\s*)|((.*[^\\w]+|\\s*)(if|while|for)\\s*\\(.*\\)\\s*))$" + } + }, + "onEnterRules": [ + { + // e.g. /** | */ + "beforeText": { + "pattern": "^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$" + }, + "afterText": { + "pattern": "^\\s*\\*/$" + }, + "action": { + "indent": "indentOutdent", + "appendText": " * " + } + }, + { + // e.g. /** ...| + "beforeText": { + "pattern": "^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$" + }, + "action": { + "indent": "none", + "appendText": " * " + } + }, + { + // e.g. * ...| + "beforeText": { + "pattern": "^(\\t|[ ])*\\*([ ]([^\\*]|\\*(?!/))*)?$" + }, + "previousLineText": { + "pattern": "(?=^(\\s*(/\\*\\*|\\*)).*)(?=(?!(\\s*\\*/)))" + }, + "action": { + "indent": "none", + "appendText": "* " + } + }, + { + // e.g. */| + "beforeText": { + "pattern": "^(\\t|[ ])*[ ]\\*/\\s*$" + }, + "action": { + "indent": "none", + "removeText": 1 + }, + }, + { + // e.g. *-----*/| + "beforeText": { + "pattern": "^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$" + }, + "action": { + "indent": "none", + "removeText": 1 + }, + }, + { + "beforeText": { + "pattern": "^\\s*(\\bcase\\s.+:|\\bdefault:)$" + }, + "afterText": { + "pattern": "^(?!\\s*(\\bcase\\b|\\bdefault\\b))" + }, + "action": { + "indent": "indent" + } + }, + { + // Decrease indentation after single line if/else if/else, for, or while + "previousLineText": "^\\s*(((else ?)?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$", + // But make sure line doesn't have braces or is not another if statement + "beforeText": "^\\s+([^{i\\s]|i(?!f\\b))", + "action": { + "indent": "outdent" + } + }, + // Indent when pressing enter from inside () + { + "beforeText": "^.*\\([^\\)]*$", + "afterText": "^\\s*\\).*$", + "action": { + "indent": "indentOutdent", + "appendText": "\t", + } + }, + // Indent when pressing enter from inside {} + { + "beforeText": "^.*\\{[^\\}]*$", + "afterText": "^\\s*\\}.*$", + "action": { + "indent": "indentOutdent", + "appendText": "\t", + } + }, + // Indent when pressing enter from inside [] + { + "beforeText": "^.*\\[[^\\]]*$", + "afterText": "^\\s*\\].*$", + "action": { + "indent": "indentOutdent", + "appendText": "\t", + } + }, + ] +} diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter-dev.html b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter-dev.html index 455e823692a94..9d853e358a06a 100644 --- a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter-dev.html +++ b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter-dev.html @@ -39,8 +39,7 @@ - - + diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter.html b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter.html index c6290004d2dd0..8d0bcc6c87c0c 100644 --- a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter.html +++ b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporter.html @@ -39,5 +39,5 @@ - + diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts index 8f4dc4a6b57a8..ca86cea6dbc6a 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts @@ -6,6 +6,7 @@ import * as dom from 'vs/base/browser/dom'; import { parentOriginHash } from 'vs/base/browser/iframe'; import { mainWindow } from 'vs/base/browser/window'; +import { isESM } from 'vs/base/common/amd'; import { Barrier } from 'vs/base/common/async'; import { VSBuffer } from 'vs/base/common/buffer'; import { canceled, onUnexpectedError } from 'vs/base/common/errors'; @@ -183,14 +184,14 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost } if (event.data.type === 'vscode.bootstrap.nls') { const factoryModuleId = 'vs/base/worker/workerMain.js'; - const baseUrl = require.toUrl(factoryModuleId).slice(0, -factoryModuleId.length); + const baseUrl = isESM ? undefined : require.toUrl(factoryModuleId).slice(0, -factoryModuleId.length); iframe.contentWindow!.postMessage({ type: event.data.type, data: { baseUrl, - workerUrl: require.toUrl(factoryModuleId), + workerUrl: isESM ? FileAccess.asBrowserUri(factoryModuleId).toString(true) : require.toUrl(factoryModuleId), + fileRoot: globalThis._VSCODE_FILE_ROOT, nls: { - // VSCODE_GLOBALS: NLS messages: globalThis._VSCODE_NLS_MESSAGES, language: globalThis._VSCODE_NLS_LANGUAGE } diff --git a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html index 3983bdb9dd4a0..0ad94fc8b3083 100644 --- a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html +++ b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html @@ -4,7 +4,7 @@ @@ -78,7 +78,7 @@ return; } const { data } = event.data; - createWorker(data.baseUrl, data.workerUrl, data.nls.messages, data.nls.language); + createWorker(data.baseUrl, data.workerUrl, data.fileRoot, data.nls.messages, data.nls.language); }; window.parent.postMessage({ @@ -87,24 +87,35 @@ }, '*'); } - function createWorker(baseUrl, workerUrl, nlsMessages, nlsLanguage) { + function createWorker(baseUrl, workerUrl, fileRoot, nlsMessages, nlsLanguage) { try { if (globalThis.crossOriginIsolated) { workerUrl += '?vscode-coi=2'; // COEP } + // ESM-comment-begin + const isESM = false; + // ESM-comment-end + // ESM-uncomment-begin + // const isESM = true; + // ESM-uncomment-end + const blob = new Blob([[ `/*extensionHostWorker*/`, `globalThis.MonacoEnvironment = { baseUrl: '${baseUrl}' };`, - // VSCODE_GLOBALS: NLS `globalThis._VSCODE_NLS_MESSAGES = ${JSON.stringify(nlsMessages)};`, `globalThis._VSCODE_NLS_LANGUAGE = ${JSON.stringify(nlsLanguage)};`, - `importScripts('${workerUrl}');`, + `globalThis._VSCODE_FILE_ROOT = '${fileRoot}';`, + isESM ? `await import('${workerUrl}');` : `importScripts('${workerUrl}');`, + isESM ? `globalThis.onmessage({ data: 'vs/workbench/api/worker/extensionHostWorker' });` : undefined, // important to start loading after the ESM async import has finished `/*extensionHostWorker*/` ].join('')], { type: 'application/javascript' }); - const worker = new Worker(URL.createObjectURL(blob), { name }); - worker.postMessage('vs/workbench/api/worker/extensionHostWorker'); + const worker = new Worker(URL.createObjectURL(blob), { name, type: isESM ? 'module' : undefined }); + if (!isESM) { + // Note: cannot postMessage into a worker that is ESM because imports are async + worker.postMessage('vs/workbench/api/worker/extensionHostWorker'); + } const nestedWorkers = new Map(); worker.onmessage = (event) => { diff --git a/test/unit/browser/index.js b/test/unit/browser/index.js index b0a0f4ddb23e0..a924cdaa5e635 100644 --- a/test/unit/browser/index.js +++ b/test/unit/browser/index.js @@ -252,7 +252,6 @@ async function runTestsInBrowser(testModules, browserType) { // when running from `out-build`, ensure to load the default // messages file, because all `nls.localize` calls have their // english values removed and replaced by an index. - // VSCODE_GLOBALS: NLS // @ts-ignore globalThis._VSCODE_NLS_MESSAGES = JSON.parse(value); }, nlsMessages); diff --git a/test/unit/electron/renderer.js b/test/unit/electron/renderer.js index d4d85a185219b..73fc7c65abee5 100644 --- a/test/unit/electron/renderer.js +++ b/test/unit/electron/renderer.js @@ -66,7 +66,7 @@ const assert = require('assert'); const path = require('path'); const glob = require('glob'); const util = require('util'); -const bootstrap = require('../../../src/bootstrap'); +const bootstrapNode = require('../../../src/bootstrap-node'); const coverage = require('../coverage'); const { takeSnapshotAndCountClasses } = require('../analyzeSnapshot'); @@ -102,7 +102,6 @@ function initNls(opts) { // when running from `out-build`, ensure to load the default // messages file, because all `nls.localize` calls have their // english values removed and replaced by an index. - // VSCODE_GLOBALS: NLS globalThis._VSCODE_NLS_MESSAGES = (require.__$__nodeRequire ?? require)(`../../../out-build/nls.messages.json`); } } @@ -116,7 +115,7 @@ function initLoader(opts) { const loaderConfig = { nodeRequire: require, catchError: true, - baseUrl: bootstrap.fileUriFromPath(path.join(__dirname, '../../../src'), { isWindows: process.platform === 'win32' }), + baseUrl: bootstrapNode.fileUriFromPath(path.join(__dirname, '../../../src'), { isWindows: process.platform === 'win32' }), paths: { 'vs': `../${outdir}/vs`, 'lib': `../${outdir}/lib`, diff --git a/test/unit/node/index.js b/test/unit/node/index.js index 9f0ec662a7345..d087e8409f3ab 100644 --- a/test/unit/node/index.js +++ b/test/unit/node/index.js @@ -17,6 +17,7 @@ const minimatch = require('minimatch'); const coverage = require('../coverage'); const minimist = require('minimist'); const { takeSnapshotAndCountClasses } = require('../analyzeSnapshot'); +const bootstrapNode = require('../../../src/bootstrap-node'); /** * @type {{ build: boolean; run: string; runGlob: string; coverage: boolean; help: boolean; coverageFormats: string | string[]; coveragePath: string; }} @@ -88,7 +89,6 @@ function main() { // when running from `out-build`, ensure to load the default // messages file, because all `nls.localize` calls have their // english values removed and replaced by an index. - // VSCODE_GLOBALS: NLS globalThis._VSCODE_NLS_MESSAGES = require(`../../../${out}/nls.messages.json`); } @@ -106,41 +106,9 @@ function main() { console.error(e.stack || e); }); - /** - * @param {string} path - * @param {{ isWindows?: boolean, scheme?: string, fallbackAuthority?: string }} config - * @returns {string} - */ - function fileUriFromPath(path, config) { - - // Since we are building a URI, we normalize any backslash - // to slashes and we ensure that the path begins with a '/'. - let pathName = path.replace(/\\/g, '/'); - if (pathName.length > 0 && pathName.charAt(0) !== '/') { - pathName = `/${pathName}`; - } - - /** @type {string} */ - let uri; - - // Windows: in order to support UNC paths (which start with '//') - // that have their own authority, we do not use the provided authority - // but rather preserve it. - if (config.isWindows && pathName.startsWith('//')) { - uri = encodeURI(`${config.scheme || 'file'}:${pathName}`); - } - - // Otherwise we optionally add the provided authority if specified - else { - uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`); - } - - return uri.replace(/#/g, '%23'); - } - const loaderConfig = { nodeRequire: require, - baseUrl: fileUriFromPath(src, { isWindows: process.platform === 'win32' }), + baseUrl: bootstrapNode.fileUriFromPath(src, { isWindows: process.platform === 'win32' }), catchError: true };