Skip to content

Commit

Permalink
fix: loader: typescript module resolver not resolving to source path …
Browse files Browse the repository at this point in the history
…of symlinked module
  • Loading branch information
AlessioGr committed Apr 28, 2024
1 parent 5bba969 commit fa2083f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/payload/src/bin/loader/index.ts
Expand Up @@ -6,6 +6,7 @@ import { fileURLToPath, pathToFileURL } from 'url'

import { CLIENT_EXTENSIONS } from './clientExtensions.js'
import { compile } from './compile.js'
import { resolveOriginalPath } from './resolveOriginalPath.js'

interface ResolveContext {
conditions: string[]
Expand Down Expand Up @@ -115,7 +116,7 @@ export const resolve: ResolveFn = async (specifier, context, nextResolve) => {
return {
format: resolvedIsTS ? 'ts' : undefined,
shortCircuit: true,
url: pathToFileURL(resolvedModule.resolvedFileName).href,
url: pathToFileURL(await resolveOriginalPath(resolvedModule.resolvedFileName)).href, // The typescript module resolver does not resolve to the original path, but to the symlinked path, if present. This can cause issues
}
}

Expand Down
35 changes: 35 additions & 0 deletions packages/payload/src/bin/loader/resolveOriginalPath.ts
@@ -0,0 +1,35 @@
import fs from 'fs/promises'
import path from 'path'

/**
* In case any directory in the path contains symlinks, this function attempts to detect that resolves the original path.
*
* Example Input: /Users/alessio/Documents/GitHub/payload-3.0-alpha-demo/node_modules/tailwindcss/resolveConfig.js
* The "tailwindcss" in this example is a symlinked directory.
*
* Example Output: /Users/alessio/Documents/GitHub/payload-3.0-alpha-demo/node_modules/.pnpm/tailwindcss@3.4.3/node_modules/tailwindcss/resolveConfig.js
*/
export async function resolveOriginalPath(filePath: string) {
try {
// Normalize and split the path
const parts = path.resolve(filePath).split(path.sep)

let currentPath = '/'
// skip the first slash
for (const part of parts.slice(1)) {
currentPath = path.join(currentPath, part)

// Check if the current path component is a symlink
const stats = await fs.lstat(currentPath)
if (stats.isSymbolicLink()) {
// Resolve the symlink
const resolvedLink = await fs.readlink(currentPath)
currentPath = path.join(path.dirname(currentPath), resolvedLink)
}
}

return currentPath
} catch (error) {
console.error('Error resolving path:', error)
}
}

0 comments on commit fa2083f

Please sign in to comment.