From 55608ca34f616f681c76f011a0f8d72f2e6f81bc Mon Sep 17 00:00:00 2001 From: gonzaloriestra <14979109+gonzaloriestra@users.noreply.github.com> Date: Sun, 14 Jun 2026 00:16:27 +0000 Subject: [PATCH] [Performance] Memoize isWsl The `isWsl` function in `packages/cli-kit/src/public/node/system.ts` performs a dynamic import of the `is-wsl` package every time it's called. While Node.js caches module imports, memoizing the result at the application level avoids the overhead of repeated module resolution lookups and promise creation. This PR memoizes the `isWsl` function by caching the promise of the dynamic import in a module-level variable. It also adds and exports an internal `_resetIsWsl` function to ensure test isolation. Unit tests have been updated and expanded to verify the memoization behavior. --- .../cli-kit/src/public/node/system.test.ts | 34 ++++++++++++++++++- packages/cli-kit/src/public/node/system.ts | 21 ++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/packages/cli-kit/src/public/node/system.test.ts b/packages/cli-kit/src/public/node/system.test.ts index ed12516ba40..5767242b39e 100644 --- a/packages/cli-kit/src/public/node/system.test.ts +++ b/packages/cli-kit/src/public/node/system.test.ts @@ -1,6 +1,6 @@ import * as system from './system.js' import {execa} from 'execa' -import {describe, expect, test, vi} from 'vitest' +import {describe, expect, test, vi, beforeEach} from 'vitest' import which from 'which' import {Readable} from 'stream' @@ -353,6 +353,38 @@ describe('isStdinPiped', () => { }) }) +describe('isWsl', () => { + beforeEach(() => { + system._resetIsWsl() + }) + + test('returns the value from is-wsl', async () => { + // Given + vi.doMock('is-wsl', () => ({ + default: true, + })) + + // When + const got = await system.isWsl() + + // Then + expect(got).toBe(true) + }) + + test('memoizes the result', async () => { + // Given + const isWslModule = await import('is-wsl') + const spy = vi.spyOn(isWslModule, 'default', 'get').mockReturnValue(true) + + // When + await system.isWsl() + await system.isWsl() + + // Then + expect(spy).toHaveBeenCalledTimes(1) + }) +}) + describe('readStdinString', () => { test('returns undefined when stdin is not piped', async () => { // Given diff --git a/packages/cli-kit/src/public/node/system.ts b/packages/cli-kit/src/public/node/system.ts index 3f449f8ff34..04bc3adf6a4 100644 --- a/packages/cli-kit/src/public/node/system.ts +++ b/packages/cli-kit/src/public/node/system.ts @@ -354,14 +354,29 @@ export function isCI(): boolean { return isTruthy(process.env.CI) } +/** + * Memoized promise for the WSL check. + */ +let memoizedIsWsl: Promise | undefined + /** * Check if the current environment is a WSL environment. * * @returns True if the current environment is a WSL environment. */ -export async function isWsl(): Promise { - const wsl = await import('is-wsl') - return wsl.default +export function isWsl(): Promise { + memoizedIsWsl ??= (async () => { + const wsl = await import('is-wsl') + return wsl.default + })() + return memoizedIsWsl +} + +/** + * Resets the memoized WSL check. + */ +export function _resetIsWsl(): void { + memoizedIsWsl = undefined } /**