From a582456912a313fac40b673756148440d856eaef Mon Sep 17 00:00:00 2001 From: neverland Date: Tue, 22 Sep 2026 13:11:30 +0800 Subject: [PATCH] perf: cache loader dynamic imports --- src/cachedImport.ts | 12 ++++++++++++ src/jiti.ts | 5 ++++- src/native.ts | 10 ++++++---- 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/cachedImport.ts diff --git a/src/cachedImport.ts b/src/cachedImport.ts new file mode 100644 index 0000000..24cae1a --- /dev/null +++ b/src/cachedImport.ts @@ -0,0 +1,12 @@ +/** Share the pending import while allowing a failed import to be retried. */ +export const cachedImport = ( + importer: () => Promise, +): (() => Promise) => { + let promise: Promise | undefined; + + return () => + (promise ??= importer().catch((error: unknown) => { + promise = undefined; + throw error; + })); +}; diff --git a/src/jiti.ts b/src/jiti.ts index a3b5523..1abba59 100644 --- a/src/jiti.ts +++ b/src/jiti.ts @@ -1,6 +1,9 @@ +import { cachedImport } from './cachedImport.js'; import { getConfigExport } from './helpers.js'; import type { ConfigDefinition, LoadedConfig } from './types.js'; +const getJiti = cachedImport(() => import('jiti')); + export const loadWithJiti = async ( configPath: string, exportName: string | false, @@ -9,7 +12,7 @@ export const loadWithJiti = async ( let createJiti: (typeof import('jiti'))['createJiti']; try { - ({ createJiti } = await import('jiti')); + ({ createJiti } = await getJiti()); } catch (error) { throw new Error( 'The "jiti" package is required to load this config. Install it with your package manager.', diff --git a/src/native.ts b/src/native.ts index 409df55..b2eb3e4 100644 --- a/src/native.ts +++ b/src/native.ts @@ -1,4 +1,9 @@ import { pathToFileURL } from 'node:url'; +import { cachedImport } from './cachedImport.js'; + +const getFreshImport = cachedImport( + () => import(/* rspackChunkName: 'freshImport' */ 'fresh-import'), +); type NativeLoadResult = { configModule: unknown; @@ -21,10 +26,7 @@ export const loadWithNative = async ( }; } - const { freshImport } = await import( - /* rspackChunkName: 'freshImport' */ - 'fresh-import' - ); + const { freshImport } = await getFreshImport(); const freshImportResult = await freshImport(configFileURL); if (freshImportResult) {