Skip to content

Commit d300b0e

Browse files
committed
Extract shared utilities from transform plugins
Created transform-utils module with reusable path extraction functions, eliminating 40+ lines of duplicated code across require-transform plugin.
1 parent d946326 commit d300b0e

File tree

2 files changed

+60
-54
lines changed

2 files changed

+60
-54
lines changed

.config/vitest-plugins/require-transform.mts

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import MagicString from 'magic-string'
99
import type { NodePath } from '@babel/traverse'
1010
import type { Plugin } from 'vite'
1111

12+
import { getDistDir, srcToDistPath } from './transform-utils.mts'
13+
1214
// Handle both ESM and CJS exports from @babel/traverse
1315
const traverse = (traverseModule as any).default || traverseModule
1416

@@ -250,34 +252,15 @@ export function createRequireTransformPlugin(
250252
return
251253
}
252254

253-
// Get the directory of the current file
254-
const currentDir = dirname(id)
255-
256255
// Build a template literal that resolves to dist/
257256
// For constants/index.ts with require(`./\${k}`):
258257
// Transform to require(`/abs/path/dist/lib/constants/\${k}`)
258+
const distDir = getDistDir(id)
259259

260-
// Find the path relative to /registry/src/lib/
261-
const libMarker = '/registry/src/lib/'
262-
const libIndex = id.indexOf(libMarker)
263-
264-
if (libIndex === -1) {
260+
if (!distDir) {
265261
return
266262
}
267263

268-
// Get the directory path relative to lib/
269-
const relativeDir = dirname(
270-
id.substring(libIndex + libMarker.length),
271-
)
272-
273-
// Build absolute dist path
274-
const projectRoot = id.substring(0, libIndex)
275-
const distDir = resolve(
276-
projectRoot,
277-
'registry/dist/lib',
278-
relativeDir,
279-
)
280-
281264
// Reconstruct the template literal with absolute dist path
282265
// Replace the leading ./ or ../ with the absolute dist path
283266
const newQuasis = arg.quasis.map((quasi, i) => {
@@ -368,44 +351,13 @@ export function createRequireTransformPlugin(
368351
// During coverage, require() can't load TypeScript files, so we use
369352
// the compiled JavaScript files from dist/ which Node can handle.
370353
const stringNode = arg as t.StringLiteral
354+
const absoluteDistPath = srcToDistPath(resolvedPath)
371355

372-
// Strategy: Use the resolvedPath (absolute path to the TypeScript source)
373-
// to determine the correct dist path with preserved directory structure.
374-
375-
// Extract the path relative to /registry/src/lib/ from the resolved source file.
376-
// Example: resolvedPath = '/abs/path/registry/src/lib/packages/normalize.ts'
377-
// relativeToLib = 'packages/normalize.ts'
378-
// Example: resolvedPath = '/abs/path/registry/src/lib/constants/WIN32.ts'
379-
// relativeToLib = 'constants/WIN32.ts'
380-
const libMarker = '/registry/src/lib/'
381-
const libIndex = resolvedPath.indexOf(libMarker)
382-
383-
if (libIndex === -1) {
356+
if (!absoluteDistPath) {
384357
// Not in lib directory, skip transformation.
385358
return
386359
}
387360

388-
// Get everything after '/registry/src/lib/' from the resolved path.
389-
// This gives us the full relative path including subdirectories.
390-
const relativeToLib = resolvedPath.substring(
391-
libIndex + libMarker.length,
392-
)
393-
394-
// Convert TypeScript extension to JavaScript.
395-
// Example: 'packages/normalize.ts' -> 'packages/normalize.js'
396-
// Example: 'constants/WIN32.ts' -> 'constants/WIN32.js'
397-
const relativeJsPath = relativeToLib.replace(/\.ts$/, '.js')
398-
399-
// Build the absolute dist path by combining project root + dist/lib + relative path.
400-
// Example: '/abs/path' + 'registry/dist/lib/' + 'packages/normalize.js'
401-
// = '/abs/path/registry/dist/lib/packages/normalize.js'
402-
const projectRoot = resolvedPath.substring(0, libIndex)
403-
const absoluteDistPath = resolve(
404-
projectRoot,
405-
'registry/dist/lib',
406-
relativeJsPath,
407-
)
408-
409361
// Replace the require string with the absolute dist path.
410362
s.overwrite(
411363
stringNode.start!,
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/** @fileoverview Shared utilities for Vitest transform plugins. */
2+
3+
import { dirname, resolve } from 'node:path'
4+
5+
const LIB_MARKER = '/registry/src/lib/'
6+
7+
interface LibPathInfo {
8+
projectRoot: string
9+
relativeToLib: string
10+
}
11+
12+
/**
13+
* Extract project root and relative path from a source file path.
14+
*/
15+
export function extractLibPath(filePath: string): LibPathInfo | null {
16+
const libIndex = filePath.indexOf(LIB_MARKER)
17+
if (libIndex === -1) {
18+
return null
19+
}
20+
21+
return {
22+
projectRoot: filePath.substring(0, libIndex),
23+
relativeToLib: filePath.substring(libIndex + LIB_MARKER.length),
24+
}
25+
}
26+
27+
/**
28+
* Convert TypeScript source path to compiled JavaScript dist path.
29+
*/
30+
export function srcToDistPath(srcPath: string): string | null {
31+
const extracted = extractLibPath(srcPath)
32+
if (!extracted) {
33+
return null
34+
}
35+
36+
const { projectRoot, relativeToLib } = extracted
37+
const relativeJsPath = relativeToLib.replace(/\.ts$/, '.js')
38+
39+
return resolve(projectRoot, 'registry/dist/lib', relativeJsPath)
40+
}
41+
42+
/**
43+
* Build absolute dist directory path for a source file.
44+
*/
45+
export function getDistDir(srcFilePath: string): string | null {
46+
const extracted = extractLibPath(srcFilePath)
47+
if (!extracted) {
48+
return null
49+
}
50+
51+
const { projectRoot, relativeToLib } = extracted
52+
53+
return resolve(projectRoot, 'registry/dist/lib', dirname(relativeToLib))
54+
}

0 commit comments

Comments
 (0)