Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Removed esbuild runtime dependency #2327

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 1 addition & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/jsapi-nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
71 changes: 26 additions & 45 deletions packages/jsapi-nodejs/src/loaderUtils.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
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';
import { ensureDirectoriesExist, getDownloadPaths } from './fsUtils.js';

type NonEmptyArray<T> = [T, ...T[]];

/** Transform downloaded content */
export type PostDownloadTransform = (
serverPath: string,
content: string
) => string;

export type LoadModuleOptions = {
serverUrl: URL;
serverPaths: NonEmptyArray<string>;
download: boolean;
download: boolean | PostDownloadTransform;
storageDir: string;
sourceModuleType: 'esm' | 'cjs';
targetModuleType?: 'esm' | 'cjs';
esbuildOptions?: Omit<
BuildOptions,
'entryPoints' | 'format' | 'outdir' | 'platform'
>;
targetModuleType: 'esm' | 'cjs';
};

/**
Expand All @@ -27,73 +27,54 @@ 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<TMainModule>({
serverUrl,
serverPaths,
download,
storageDir,
sourceModuleType,
targetModuleType = sourceModuleType,
esbuildOptions,
targetModuleType,
}: LoadModuleOptions): Promise<TMainModule> {
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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should mention this change in the PR description as well - it's now downloading to the serverStorageDir instead of a target subdirectory.

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);
Expand Down
Loading