Skip to content

Commit

Permalink
refactor: Update loader.
Browse files Browse the repository at this point in the history
  • Loading branch information
darkobits committed Nov 3, 2023
1 parent 728df49 commit 797c6e8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 21 deletions.
20 changes: 11 additions & 9 deletions src/lib/configuration/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,24 @@ async function ecmaScriptLoader(filePath: string /* , contents: string */) {
}


/**
* Gather information about the package containing `filePath`, required for
* subsequent strategies.
*/
const pkgInfo = getPackageInfo({ cwd: path.dirname(filePath) });
if (!pkgInfo?.root) throw new Error(`${prefix} Unable to compute host package root directory.`);


/**
* Strategy 2: esbuild
*
* Uses esbuild to transpile the indicated file.
*/
try {
const result = await esbuildStrategy(filePath, pkgInfo);
const pkgInfo = getPackageInfo({ cwd: path.dirname(filePath) });
if (!pkgInfo?.root) throw new Error(`${prefix} Unable to compute host package root directory.`);

const result = await esbuildStrategy(filePath, {
pkg: {
root: pkgInfo.root,
type: pkgInfo.json?.type
}
});

log.verbose(prefix, 'Used strategy:', log.chalk.bold('esbuild'));

return getDefaultExport(result);
} catch (err: any) {
errors.push(new Error(`${prefix} Failed to load file with ${log.chalk.bold('esbuild')}: ${err}`));
Expand Down
39 changes: 27 additions & 12 deletions src/lib/configuration/strategies/esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,52 @@ import * as esbuild from 'esbuild';
import { nodeExternalsPlugin } from 'esbuild-node-externals';
import { getTsconfig } from 'get-tsconfig';


import log from 'lib/log';

import type { PackageInfo } from 'lib/package';


/**
* Map of input extensions to output extensions that Node can natively import.
* @private
*
* Map of supported input extensions to a corresponding output extension that
* Node can natively import.
*/
const EXT_MAP: Record<string, string> = {
'.js': '.js',
'.ts': '.js',
'.tsx': '.js',
'.jsx':' .js',
// User explicitly wants CommonJS.
'.cts': '.cjs',
'.cjs': '.cjs',
'.cts': '.cjs',
// User explicitly wants ESM.
'.mts': '.mjs',
'.mjs': '.mjs'
'.mjs': '.mjs',
'.mts': '.mjs'
};


export interface EsbuildStrategyOptions {
pkg: {
type: 'module' | 'commonjs' | undefined;
root: string;
};
}


/**
* Uses esbuild to transpile the file at `filePath` by creating a temporary
* file in the same directory, then attempts to dynamically import it. An
* output format and extension are chosen based on the host project's
* "type" setting that are the least likely to produce errors. Once imported,
* the temporary file is removed.
* output format and extension are chosen based on the host project's "type"
* setting that are the least likely to produce errors. Once imported, the
* temporary file is removed.
*
* The `pkgInfo` parameter is needed to determine the "type"
*
* The optional type argument `M` may be used to specify the shape of the
* imported module.
*/
export async function esbuildStrategy<M = any>(filePath: string, pkgInfo: PackageInfo): Promise<M> {
export async function esbuildStrategy<M = any>(filePath: string, opts: EsbuildStrategyOptions): Promise<M> {
const prefix = log.prefix('strategy:esbuild');

const parsedFilePath = path.parse(filePath);
Expand All @@ -56,7 +71,7 @@ export async function esbuildStrategy<M = any>(filePath: string, pkgInfo: Packag
? 'esm'
: isExplicitCommonJs
? 'cjs'
: pkgInfo.json?.type === 'module'
: opts.pkg.type === 'module'
? 'esm'
: 'cjs';

Expand All @@ -77,7 +92,7 @@ export async function esbuildStrategy<M = any>(filePath: string, pkgInfo: Packag
bundle: true,
plugins: [
nodeExternalsPlugin({
packagePath: path.resolve(pkgInfo.root ?? '', 'package.json')
packagePath: path.resolve(opts.pkg.root ?? '', 'package.json')
})
]
};
Expand Down Expand Up @@ -113,7 +128,7 @@ export async function esbuildStrategy<M = any>(filePath: string, pkgInfo: Packag
{ cause: err }
);
} finally {
// Remove the temporary file.
// Remove the temporary file.f
await fs.access(tempFilePath, fs.constants.F_OK)
.then(() => fs.unlink(tempFilePath));
}
Expand Down

0 comments on commit 797c6e8

Please sign in to comment.