From a829c735864bf806d27ed3a8b33da5db72ff9862 Mon Sep 17 00:00:00 2001 From: Brian Ingles Date: Thu, 2 Jan 2025 13:11:09 -0600 Subject: [PATCH] Removed esbuild runtime dependency (DH-18191) --- package-lock.json | 25 +-------- packages/jsapi-nodejs/package.json | 6 +- packages/jsapi-nodejs/src/loaderUtils.ts | 71 +++++++++--------------- 3 files changed, 28 insertions(+), 74 deletions(-) diff --git a/package-lock.json b/package-lock.json index 97cbe95cc..dfd062917 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13689,18 +13689,6 @@ "@esbuild/win32-x64": "0.21.5" } }, - "node_modules/esbuild-wasm": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.0.tgz", - "integrity": "sha512-xhNn5tL1AhkPg4ft59yXT6FkwKXiPSYyz1IeinJHUJpjvOHOIPvdmFQc0pGdjxlKSbzZc2mNmtVOWAR1EF/JAg==", - "dev": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/escalade": { "version": "3.1.1", "license": "MIT", @@ -30227,14 +30215,10 @@ }, "devDependencies": { "@types/node": "^22.7.5", - "@types/ws": "^8.5.12", - "esbuild-wasm": "^0.24.0" + "@types/ws": "^8.5.12" }, "engines": { "node": ">=16" - }, - "peerDependencies": { - "esbuild-wasm": "^0.24.0" } }, "packages/jsapi-nodejs/node_modules/@types/node": { @@ -32524,7 +32508,6 @@ "requires": { "@types/node": "^22.7.5", "@types/ws": "^8.5.12", - "esbuild-wasm": "^0.24.0", "ws": "^8.18.0" }, "dependencies": { @@ -41238,12 +41221,6 @@ "@esbuild/win32-x64": "0.21.5" } }, - "esbuild-wasm": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.0.tgz", - "integrity": "sha512-xhNn5tL1AhkPg4ft59yXT6FkwKXiPSYyz1IeinJHUJpjvOHOIPvdmFQc0pGdjxlKSbzZc2mNmtVOWAR1EF/JAg==", - "dev": true - }, "escalade": { "version": "3.1.1" }, diff --git a/packages/jsapi-nodejs/package.json b/packages/jsapi-nodejs/package.json index 9050c688b..31b408bee 100644 --- a/packages/jsapi-nodejs/package.json +++ b/packages/jsapi-nodejs/package.json @@ -25,11 +25,7 @@ }, "devDependencies": { "@types/node": "^22.7.5", - "@types/ws": "^8.5.12", - "esbuild-wasm": "^0.24.0" - }, - "peerDependencies": { - "esbuild-wasm": "^0.24.0" + "@types/ws": "^8.5.12" }, "files": [ "dist" diff --git a/packages/jsapi-nodejs/src/loaderUtils.ts b/packages/jsapi-nodejs/src/loaderUtils.ts index 0ae8194ec..f9b5ee3f4 100644 --- a/packages/jsapi-nodejs/src/loaderUtils.ts +++ b/packages/jsapi-nodejs/src/loaderUtils.ts @@ -1,6 +1,5 @@ import fs from 'node:fs'; import path from 'node:path'; -import esbuild, { type BuildOptions } from 'esbuild-wasm'; import { downloadFromURL, urlToDirectoryName } from './serverUtils.js'; import { polyfillWs } from './polyfillWs.js'; @@ -8,17 +7,18 @@ import { ensureDirectoriesExist, getDownloadPaths } from './fsUtils.js'; type NonEmptyArray = [T, ...T[]]; +/** Transform downloaded content */ +export type PostDownloadTransform = ( + serverPath: string, + content: string +) => string; + export type LoadModuleOptions = { serverUrl: URL; serverPaths: NonEmptyArray; - download: boolean; + download: boolean | PostDownloadTransform; storageDir: string; - sourceModuleType: 'esm' | 'cjs'; - targetModuleType?: 'esm' | 'cjs'; - esbuildOptions?: Omit< - BuildOptions, - 'entryPoints' | 'format' | 'outdir' | 'platform' - >; + targetModuleType: 'esm' | 'cjs'; }; /** @@ -27,12 +27,12 @@ export type LoadModuleOptions = { * @param serverPaths The paths of the modules on the server. * @param download Whether to download the modules from the server. If set to false, * it's assumed that the modules have already been downloaded and still exist in - * the storage directory. + * the storage directory. If set to `true` or a `PostDownloadTransform` function, + * the modules will be downloaded and stored. If set to a `PostDownloadTransform` + * function, the downloaded content will be passed to the function and the result + * saved to disk. * @param storageDir The directory to store the downloaded modules. - * @param sourceModuleType module format from the server. - * @param targetModuleType (optional) module format to be exported. Defaults to - * sourceModuleType. - * @param esbuildOptions (optional) Additional options to pass to esbuild. + * @param targetModuleType The type of module to load. Can be either 'esm' or 'cjs'. * @returns The default export of the first module in `serverPaths`. */ export async function loadModules({ @@ -40,60 +40,41 @@ export async function loadModules({ serverPaths, download, storageDir, - sourceModuleType, - targetModuleType = sourceModuleType, - esbuildOptions, + targetModuleType, }: LoadModuleOptions): Promise { polyfillWs(); const serverStorageDir = path.join(storageDir, urlToDirectoryName(serverUrl)); - const targetDir = path.join(serverStorageDir, 'target'); - - if (download) { - const needsTranspile = sourceModuleType !== targetModuleType; - const sourceDir = path.join(serverStorageDir, 'source'); - ensureDirectoriesExist( - needsTranspile ? [sourceDir, targetDir] : [targetDir] - ); + if (download !== false) { + ensureDirectoriesExist([serverStorageDir]); // Download from server const serverUrls = serverPaths.map( serverPath => new URL(serverPath, serverUrl) ); - const contents = await Promise.all( + let contents = await Promise.all( serverUrls.map(url => downloadFromURL(url)) ); + // Post-download transform + if (typeof download === 'function') { + contents = contents.map((content, i) => + download(serverPaths[i], content) + ); + } + // Write to disk - const downloadPaths = getDownloadPaths( - needsTranspile ? sourceDir : targetDir, - serverPaths - ); + const downloadPaths = getDownloadPaths(serverStorageDir, serverPaths); downloadPaths.forEach((downloadPath, i) => { fs.writeFileSync(downloadPath, contents[i]); }); - - // Transpile if source and target module types differ - if (needsTranspile) { - await esbuild.build({ - // These can be overridden by esbuildOptions - bundle: false, - logLevel: 'error', - ...esbuildOptions, - // These cannot be overridden - entryPoints: downloadPaths, - format: targetModuleType, - outdir: targetDir, - platform: 'node', - }); - } } // We assume the first module is the main module // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const firstFileName = serverPaths[0].split('/').pop()!; - const mainModulePath = path.join(targetDir, firstFileName); + const mainModulePath = path.join(serverStorageDir, firstFileName); if (targetModuleType === 'esm') { return import(mainModulePath);