From 23b60c77491cff303065c15c06c3a01621dceca6 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Mon, 3 Aug 2026 13:46:31 -0700 Subject: [PATCH 1/2] Enable native ESM extension bundle Emit the packaged extension as an ES module while preserving CommonJS dependency compatibility through createRequire. Include the ESM artifact in debugging and signing. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 720632a5-5bd9-43bb-9349-6c1a02fe3347 --- .vscode/launch.json | 14 +++++++------- esbuild.js | 7 +++++-- msbuild/signing/signJs/signJs.proj | 3 +++ package.json | 4 ++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 6b21f9497a..6f97b6ac3f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "runtimeExecutable": "${execPath}", "args": ["--extensionDevelopmentPath=${workspaceRoot}"], "sourceMaps": true, - "outFiles": ["${workspaceRoot}/dist/*.js"], + "outFiles": ["${workspaceRoot}/dist/*.{js,mjs}"], "preLaunchTask": "packageDev" }, { @@ -33,7 +33,7 @@ }, "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/dist/*.js", + "${workspaceRoot}/dist/*.{js,mjs}", "${workspaceRoot}/out/test/**/*.js" ], "resolveSourceMapLocations": [ @@ -66,7 +66,7 @@ "RoslynWaiterEnabled": "true" }, "sourceMaps": true, - "outFiles": ["${workspaceRoot}/dist/*.js", "${workspaceRoot}/out/test/**/*.js"], + "outFiles": ["${workspaceRoot}/dist/*.{js,mjs}", "${workspaceRoot}/out/test/**/*.js"], "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"], "preLaunchTask": "packageDev", "internalConsoleOptions": "openOnSessionStart" @@ -94,7 +94,7 @@ "RoslynWaiterEnabled": "true" }, "sourceMaps": true, - "outFiles": ["${workspaceRoot}/dist/*.js", "${workspaceRoot}/out/test/**/*.js"], + "outFiles": ["${workspaceRoot}/dist/*.{js,mjs}", "${workspaceRoot}/out/test/**/*.js"], "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"], "preLaunchTask": "packageDev", "internalConsoleOptions": "openOnSessionStart" @@ -121,7 +121,7 @@ "TEST_FILE_FILTER": "${file}" }, "sourceMaps": true, - "outFiles": ["${workspaceRoot}/dist/*.js", "${workspaceRoot}/out/test/**/*.js"], + "outFiles": ["${workspaceRoot}/dist/*.{js,mjs}", "${workspaceRoot}/out/test/**/*.js"], "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"], "preLaunchTask": "packageDev", "internalConsoleOptions": "openOnSessionStart" @@ -147,7 +147,7 @@ "TEST_FILE_FILTER": "${file}" }, "sourceMaps": true, - "outFiles": ["${workspaceRoot}/dist/*.js", "${workspaceRoot}/out/test/**/*.js"], + "outFiles": ["${workspaceRoot}/dist/*.{js,mjs}", "${workspaceRoot}/out/test/**/*.js"], "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"], "preLaunchTask": "packageDev" }, @@ -172,7 +172,7 @@ "TEST_FILE_FILTER": "${file}" }, "sourceMaps": true, - "outFiles": ["${workspaceRoot}/dist/*.js", "${workspaceRoot}/out/test/**/*.js"], + "outFiles": ["${workspaceRoot}/dist/*.{js,mjs}", "${workspaceRoot}/out/test/**/*.js"], "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"], "preLaunchTask": "packageDev" }, diff --git a/esbuild.js b/esbuild.js index 54ff1c1803..a83d1c7f82 100644 --- a/esbuild.js +++ b/esbuild.js @@ -48,12 +48,15 @@ async function main() { 'src/main.ts' ], bundle: true, - format: 'cjs', + format: 'esm', + banner: { + js: `import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);`, + }, minify: production, sourcemap: !production, sourcesContent: false, platform: 'node', - outfile: 'dist/extension.js', + outfile: 'dist/extension.mjs', external: ['vscode', 'applicationinsights-native-metrics', '@opentelemetry/tracing'], logLevel: 'info', plugins: [ diff --git a/msbuild/signing/signJs/signJs.proj b/msbuild/signing/signJs/signJs.proj index c2cd518069..502447df9a 100644 --- a/msbuild/signing/signJs/signJs.proj +++ b/msbuild/signing/signJs/signJs.proj @@ -21,5 +21,8 @@ MicrosoftSHA2 + + MicrosoftSHA2 + \ No newline at end of file diff --git a/package.json b/package.json index c1fcd5e961..0fc62c1471 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "xamlTools": "18.10.12014.341", "testDiscovery": "9.9.223-ge3811b" }, - "main": "./dist/extension", + "main": "./dist/extension.mjs", "l10n": "./l10n", "brokeredServices": [ { @@ -81,7 +81,7 @@ "omnisharptest": "npm run packageDev && npx ts-node tasks/tests/omnisharptest.ts", "omnisharptest:integration": "npm run packageDev && npx ts-node tasks/tests/omnisharptestIntegration.ts", "omnisharptest:unit": "npm run compileDev && npx ts-node tasks/tests/omnisharptestUnit.ts", - "package": "npm run compile && npm run signJs && node esbuild.js --production", + "package": "npm run compile && node esbuild.js --production && npm run signJs", "packageDev": "npm run compileDev && node esbuild.js", "prepare": "npm run installDependencies", "profiling": "npm run package && npx ts-node tasks/profiling/profiling.ts", From bf96ad36dccdcb799bd838345db8c693503ba147 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Mon, 3 Aug 2026 17:35:35 -0700 Subject: [PATCH 2/2] Provide CommonJS globals in ESM bundle Temporarily define module-relative __filename and __dirname in the ESM banner so bundled CommonJS source continues to activate until its usages are converted. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 31a04314-b84f-48a8-8614-6538bce8352a --- esbuild.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/esbuild.js b/esbuild.js index a83d1c7f82..f34c5912ac 100644 --- a/esbuild.js +++ b/esbuild.js @@ -50,7 +50,15 @@ async function main() { bundle: true, format: 'esm', banner: { - js: `import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);`, + js: [ + `import { createRequire } from 'node:module';`, + `import { dirname as commonJsDirname } from 'node:path';`, + `import { fileURLToPath as commonJsFileURLToPath } from 'node:url';`, + `const require = createRequire(import.meta.url);`, + `// Temporary CommonJS globals until bundled source usages are converted to ESM.`, + `const __filename = commonJsFileURLToPath(import.meta.url);`, + `const __dirname = commonJsDirname(__filename);`, + ].join('\n'), }, minify: production, sourcemap: !production,