From 3c76ee5b2174b93c68905c5c8caeb0b375ac9737 Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Thu, 11 Apr 2024 12:14:06 -0400 Subject: [PATCH 1/2] feat(dev-tools): Inline ESM-only dependency --- .../src/configuration/get-esbuild-config.ts | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/modules/dev-tools/src/configuration/get-esbuild-config.ts b/modules/dev-tools/src/configuration/get-esbuild-config.ts index 468a8766..c5c2f50c 100644 --- a/modules/dev-tools/src/configuration/get-esbuild-config.ts +++ b/modules/dev-tools/src/configuration/get-esbuild-config.ts @@ -4,7 +4,7 @@ import {join} from 'path'; import util from 'util'; import {getOcularConfig} from '../helpers/get-ocular-config.js'; import ext from 'esbuild-plugin-external-global'; -import type {BuildOptions} from 'esbuild'; +import type {BuildOptions, Plugin} from 'esbuild'; /** * Get list of dependencies to exclude using esbuild-plugin-external-global @@ -67,6 +67,26 @@ function umdWrapper(libName: string | undefined) { }; } +/** + * ESBuild plugin to inline important ESM-only dependencies, for CJS compatibility. + * Reference: https://github.com/evanw/esbuild/issues/3442 + */ +const inlineESMOnly = (): Plugin => { + const packageRoot = process.cwd(); + const root = join(packageRoot, '../..'); + + return { + name: 'inline-esm-only', + setup(build) { + // TODO: Detect ESM-only from package.json, instead of hard-coding package names? + build.onResolve({filter: /^@mapbox\/tiny\-sdf$/}, () => { + const path = join(root, 'node_modules/@mapbox/tiny-sdf/index.js'); + return {path, external: false}; + }); + } + }; +}; + /** Returns esbuild config for building .cjs bundles */ export async function getCJSExportConfig(opts: { input: string; @@ -81,7 +101,8 @@ export async function getCJSExportConfig(opts: { target: 'node16', packages: 'external', sourcemap: true, - logLevel: 'info' + logLevel: 'info', + plugins: [inlineESMOnly()] }; } From 52ed6b2dfabc97a16795333e3e3ea2a58fa0ae0c Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Thu, 11 Apr 2024 14:01:47 -0400 Subject: [PATCH 2/2] Use package root, not workspace root. Keep prod dependency for ESM. --- modules/dev-tools/src/configuration/get-esbuild-config.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/dev-tools/src/configuration/get-esbuild-config.ts b/modules/dev-tools/src/configuration/get-esbuild-config.ts index c5c2f50c..ed07a506 100644 --- a/modules/dev-tools/src/configuration/get-esbuild-config.ts +++ b/modules/dev-tools/src/configuration/get-esbuild-config.ts @@ -73,14 +73,13 @@ function umdWrapper(libName: string | undefined) { */ const inlineESMOnly = (): Plugin => { const packageRoot = process.cwd(); - const root = join(packageRoot, '../..'); return { name: 'inline-esm-only', setup(build) { // TODO: Detect ESM-only from package.json, instead of hard-coding package names? build.onResolve({filter: /^@mapbox\/tiny\-sdf$/}, () => { - const path = join(root, 'node_modules/@mapbox/tiny-sdf/index.js'); + const path = join(packageRoot, 'node_modules/@mapbox/tiny-sdf/index.js'); return {path, external: false}; }); }