From ab8f4ebca62ae5bfcb0ffb10110d1a085d935fef Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Fri, 18 Oct 2024 10:05:15 -0600 Subject: [PATCH] Smarter path handling --- src/lib/utils/plugins.ts | 26 +++++++++++++++++++------- src/test/utils/plugins.test.ts | 18 +++++++++++++++++- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/lib/utils/plugins.ts b/src/lib/utils/plugins.ts index 3589241a7..7c70c4a1a 100644 --- a/src/lib/utils/plugins.ts +++ b/src/lib/utils/plugins.ts @@ -13,13 +13,25 @@ export async function loadPlugins( const pluginDisplay = getPluginDisplayName(plugin); try { - // On Windows, we need to ensure this path is a file path. - // Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME - const esmPath = isAbsolute(plugin) - ? pathToFileURL(plugin).toString() - : plugin; - let instance: any = await import(esmPath); - const initFunction = instance.load || instance.default?.load; + let instance: any; + // Try importing first to avoid warnings about requiring ESM being experimental. + // If that fails due to importing a directory, fall back to require. + try { + // On Windows, we need to ensure this path is a file path. + // Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME + const esmPath = isAbsolute(plugin) + ? pathToFileURL(plugin).toString() + : plugin; + instance = await import(esmPath); + } catch (error: any) { + if (error.code === "ERR_UNSUPPORTED_DIR_IMPORT") { + // eslint-disable-next-line @typescript-eslint/no-require-imports + instance = require(plugin); + } else { + throw error; + } + } + const initFunction = instance.load; if (typeof initFunction === "function") { await initFunction(app); diff --git a/src/test/utils/plugins.test.ts b/src/test/utils/plugins.test.ts index 17705534c..47a64fa9d 100644 --- a/src/test/utils/plugins.test.ts +++ b/src/test/utils/plugins.test.ts @@ -14,7 +14,7 @@ describe("loadPlugins", () => { logger = fakeApp.logger = new TestLogger(); }); - it("Should support loading a basic plugin", async () => { + it("Should support loading a CJS plugin with directory target", async () => { using project = tempdirProject(); project.addJsonFile("package.json", { type: "commonjs", @@ -28,6 +28,22 @@ describe("loadPlugins", () => { logger.expectMessage(`info: Loaded plugin ${plugin}`); }); + it("Should support loading a CJS plugin with full path", async () => { + using project = tempdirProject(); + project.addJsonFile("package.json", { + type: "commonjs", + main: "index.js", + }); + const plugin = project.addFile( + "index.js", + "exports.load = function load() {}", + ).path; + project.write(); + + await loadPlugins(fakeApp, [plugin]); + logger.expectMessage(`info: Loaded plugin ${plugin}`); + }); + it("Should support loading a ESM plugin", async () => { using project = tempdirProject(); project.addJsonFile("package.json", {