From e2b89bb3ce5b1674b3b9d0a704c71afefdec182e Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Fri, 5 Dec 2025 19:11:33 +0100 Subject: [PATCH 1/4] refactor: use jiti in favour of bundle-require --- package-lock.json | 2 +- package.json | 2 +- packages/utils/src/lib/file-system.ts | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index deb4b547d..3ca177c26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,7 +92,7 @@ "husky": "^8.0.0", "inquirer": "^9.3.7", "jest-extended": "^6.0.0", - "jiti": "2.4.2", + "jiti": "^2.4.2", "jsdom": "~24.0.0", "jsonc-eslint-parser": "^2.4.0", "knip": "^5.33.3", diff --git a/package.json b/package.json index e4c55ca77..ffa649f64 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "husky": "^8.0.0", "inquirer": "^9.3.7", "jest-extended": "^6.0.0", - "jiti": "2.4.2", + "jiti": "^2.4.2", "jsdom": "~24.0.0", "jsonc-eslint-parser": "^2.4.0", "knip": "^5.33.3", diff --git a/packages/utils/src/lib/file-system.ts b/packages/utils/src/lib/file-system.ts index 5dacec734..8d34a277a 100644 --- a/packages/utils/src/lib/file-system.ts +++ b/packages/utils/src/lib/file-system.ts @@ -1,5 +1,5 @@ import ansis from 'ansis'; -import { type Options, bundleRequire } from 'bundle-require'; +import { type JitiOptions, createJiti } from 'jiti'; import { mkdir, readFile, readdir, rm, stat } from 'node:fs/promises'; import path from 'node:path'; import type { Format, PersistConfig } from '@code-pushup/models'; @@ -77,8 +77,11 @@ export function logMultipleFileResults( ); } -export async function importModule(options: Options): Promise { - const { mod } = await bundleRequire(options); +const jitiImport = createJiti(process.cwd()); +export async function importModule({ + filepath, +}: JitiOptions): Promise { + const { mod } = await jitiImport(filepath); if (typeof mod === 'object' && 'default' in mod) { return mod.default as T; From 00197b9fb43559cd145cb39c6ccf4242f21f9555 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Fri, 5 Dec 2025 19:16:29 +0100 Subject: [PATCH 2/4] refactor: derive jiti types --- packages/utils/src/lib/file-system.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/utils/src/lib/file-system.ts b/packages/utils/src/lib/file-system.ts index 8d34a277a..7c067af0c 100644 --- a/packages/utils/src/lib/file-system.ts +++ b/packages/utils/src/lib/file-system.ts @@ -1,5 +1,5 @@ import ansis from 'ansis'; -import { type JitiOptions, createJiti } from 'jiti'; +import { createJiti } from 'jiti'; import { mkdir, readFile, readdir, rm, stat } from 'node:fs/promises'; import path from 'node:path'; import type { Format, PersistConfig } from '@code-pushup/models'; @@ -78,9 +78,12 @@ export function logMultipleFileResults( } const jitiImport = createJiti(process.cwd()); -export async function importModule({ - filepath, -}: JitiOptions): Promise { +type JitiOptions = Parameters[1]; + +export async function importModule( + options: JitiOptions & { filepath: string }, +): Promise { + const { filepath } = options; const { mod } = await jitiImport(filepath); if (typeof mod === 'object' && 'default' in mod) { From b7f9b4dc0c4298d164c0260e69179fbdc100aae9 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Fri, 5 Dec 2025 19:41:45 +0100 Subject: [PATCH 3/4] refactor: wip --- .../src/lib/implementation/read-rc-file.ts | 1 - packages/utils/src/lib/file-system.ts | 75 +++++++++++++++++-- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/packages/core/src/lib/implementation/read-rc-file.ts b/packages/core/src/lib/implementation/read-rc-file.ts index 9dd2afb5f..d91128fae 100644 --- a/packages/core/src/lib/implementation/read-rc-file.ts +++ b/packages/core/src/lib/implementation/read-rc-file.ts @@ -29,7 +29,6 @@ export async function readRcByPath( const cfg: CoreConfig = await importModule({ filepath: filePath, tsconfig, - format: 'esm', }); return validate(coreConfigSchema, cfg, { filePath }); diff --git a/packages/utils/src/lib/file-system.ts b/packages/utils/src/lib/file-system.ts index 7c067af0c..8c1f7896b 100644 --- a/packages/utils/src/lib/file-system.ts +++ b/packages/utils/src/lib/file-system.ts @@ -2,6 +2,7 @@ import ansis from 'ansis'; import { createJiti } from 'jiti'; import { mkdir, readFile, readdir, rm, stat } from 'node:fs/promises'; import path from 'node:path'; +import { parseJsonConfigFileContent, readConfigFile, sys } from 'typescript'; import type { Format, PersistConfig } from '@code-pushup/models'; import { formatBytes } from './formatting.js'; import { logMultipleResults } from './log-results.js'; @@ -77,16 +78,80 @@ export function logMultipleFileResults( ); } -const jitiImport = createJiti(process.cwd()); +export function loadTargetConfig(tsConfigPath: string) { + const resolvedConfigPath = path.resolve(tsConfigPath); + const { config, error } = readConfigFile(resolvedConfigPath, sys.readFile); + + if (error) { + throw new Error( + `Error reading TypeScript config file at ${tsConfigPath}:\n${error.messageText}`, + ); + } + + const parsedConfig = parseJsonConfigFileContent( + config, + sys, + path.dirname(resolvedConfigPath), + {}, + resolvedConfigPath, + ); + + if (parsedConfig.fileNames.length === 0) { + throw new Error( + 'No files matched by the TypeScript configuration. Check your "include", "exclude" or "files" settings.', + ); + } + + return parsedConfig; +} + type JitiOptions = Parameters[1]; +export function tsConfigToJitiOptionsTransformer( + tsConfigPath: string, +): JitiOptions { + const parsedConfig = loadTargetConfig(tsConfigPath); + const compilerOptions = parsedConfig.options; + + const jitiOptions: JitiOptions = {}; + + if (compilerOptions.paths) { + const aliases: Record = {}; + const basePath = compilerOptions.baseUrl || path.dirname(tsConfigPath); + + for (const alias in compilerOptions.paths) { + const paths = compilerOptions.paths[alias]; + if (paths && paths.length > 0) { + aliases[alias] = path.resolve(basePath, paths[0] as string); + } + } + jitiOptions.alias = aliases; + } + + if (compilerOptions.jsx) { + jitiOptions.jsx = true; + } + + return jitiOptions; +} + export async function importModule( - options: JitiOptions & { filepath: string }, + options: JitiOptions & { filepath: string; tsconfig?: string }, ): Promise { - const { filepath } = options; - const { mod } = await jitiImport(filepath); + const { filepath, tsconfig, ...jitiOptions } = options; + + const jitiOptionsFromTsConfig = tsconfig + ? tsConfigToJitiOptionsTransformer(tsconfig) + : {}; + + const jiti = createJiti(process.cwd(), { + ...jitiOptions, + ...jitiOptionsFromTsConfig, + }); + + const mod = await jiti.import(filepath); - if (typeof mod === 'object' && 'default' in mod) { + if (mod && typeof mod === 'object' && 'default' in mod) { return mod.default as T; } return mod as T; From 44c5cc3a09e3da8541db7d343fcb2af454d5d160 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Fri, 5 Dec 2025 19:48:43 +0100 Subject: [PATCH 4/4] refactor: wip --- packages/plugin-coverage/src/lib/nx/coverage-paths.ts | 1 - packages/plugin-lighthouse/src/lib/runner/utils.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/plugin-coverage/src/lib/nx/coverage-paths.ts b/packages/plugin-coverage/src/lib/nx/coverage-paths.ts index 12a708134..69eba3c15 100644 --- a/packages/plugin-coverage/src/lib/nx/coverage-paths.ts +++ b/packages/plugin-coverage/src/lib/nx/coverage-paths.ts @@ -136,7 +136,6 @@ export async function getCoveragePathForVitest( const vitestConfig = await importModule({ filepath: config, - format: 'esm', }); const reportsDirectory = diff --git a/packages/plugin-lighthouse/src/lib/runner/utils.ts b/packages/plugin-lighthouse/src/lib/runner/utils.ts index 50a4ed47e..48f0a4d2d 100644 --- a/packages/plugin-lighthouse/src/lib/runner/utils.ts +++ b/packages/plugin-lighthouse/src/lib/runner/utils.ts @@ -134,7 +134,7 @@ export async function getConfig( // Resolve the config file path relative to where cli was called. return readJsonFile(filepath); } else if (/\.(ts|js|mjs)$/.test(filepath)) { - return importModule({ filepath, format: 'esm' }); + return importModule({ filepath }); } else { logger.warn(`Format of file ${filepath} not supported`); }