|
| 1 | +diff --git a/dist/build/copyTracedFiles.js b/dist/build/copyTracedFiles.js |
| 2 | +index 9701b0401e987ee7cd696873af9d15b751580c52..61c62b3b16205b4d043f92e9e3c5bb5f2c2415d1 100644 |
| 3 | +--- a/dist/build/copyTracedFiles.js |
| 4 | ++++ b/dist/build/copyTracedFiles.js |
| 5 | +@@ -1,3 +1,4 @@ |
| 6 | ++import { createRequire } from "node:module"; |
| 7 | + import url from "node:url"; |
| 8 | + import { chmodSync, copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs"; |
| 9 | + import path from "node:path"; |
| 10 | +@@ -46,6 +47,111 @@ const nonLinuxPlatformRegex = getCrossPlatformPathRegex(`/node_modules/(?:@[^/]+ |
| 11 | + export function isNonLinuxPlatformPackage(srcPath) { |
| 12 | + return nonLinuxPlatformRegex.test(srcPath); |
| 13 | + } |
| 14 | ++function collectImportTargets(value, out) { |
| 15 | ++ if (typeof value === "string") { |
| 16 | ++ out.push(value); |
| 17 | ++ } |
| 18 | ++ else if (Array.isArray(value)) { |
| 19 | ++ value.forEach((v) => collectImportTargets(v, out)); |
| 20 | ++ } |
| 21 | ++ else if (value && typeof value === "object") { |
| 22 | ++ Object.values(value).forEach((v) => collectImportTargets(v, out)); |
| 23 | ++ } |
| 24 | ++} |
| 25 | ++function augmentWithImportsRemaps(filesToCopy, buildOutputPath) { |
| 26 | ++ const visitedConsumers = new Set(); |
| 27 | ++ const projectRequire = createRequire(path.join(buildOutputPath, "package.json")); |
| 28 | ++ const pending = []; |
| 29 | ++ for (const [src, dst] of filesToCopy) { |
| 30 | ++ if (src.endsWith("/package.json")) |
| 31 | ++ pending.push([src, dst]); |
| 32 | ++ } |
| 33 | ++ while (pending.length) { |
| 34 | ++ const [pkgSrc, pkgDst] = pending.shift(); |
| 35 | ++ if (visitedConsumers.has(pkgSrc)) |
| 36 | ++ continue; |
| 37 | ++ visitedConsumers.add(pkgSrc); |
| 38 | ++ let pkg; |
| 39 | ++ try { |
| 40 | ++ pkg = JSON.parse(readFileSync(pkgSrc, "utf-8")); |
| 41 | ++ } |
| 42 | ++ catch { |
| 43 | ++ continue; |
| 44 | ++ } |
| 45 | ++ if (!pkg.imports || typeof pkg.imports !== "object") |
| 46 | ++ continue; |
| 47 | ++ const consumerName = typeof pkg.name === "string" ? pkg.name : ""; |
| 48 | ++ const upLevels = consumerName.startsWith("@") ? 2 : 1; |
| 49 | ++ const consumerSrcDir = path.dirname(pkgSrc); |
| 50 | ++ const consumerDstDir = path.dirname(pkgDst); |
| 51 | ++ const dstNodeModules = path.resolve(consumerDstDir, "../".repeat(upLevels)); |
| 52 | ++ // Consumer resolves deps via its own source location in the real project. |
| 53 | ++ const realConsumerDir = consumerName |
| 54 | ++ ? (() => { |
| 55 | ++ try { |
| 56 | ++ return path.dirname(projectRequire.resolve(`${consumerName}/package.json`)); |
| 57 | ++ } |
| 58 | ++ catch { |
| 59 | ++ return consumerSrcDir; |
| 60 | ++ } |
| 61 | ++ })() |
| 62 | ++ : consumerSrcDir; |
| 63 | ++ const consumerRequire = createRequire(path.join(realConsumerDir, "package.json")); |
| 64 | ++ const targets = []; |
| 65 | ++ for (const v of Object.values(pkg.imports)) |
| 66 | ++ collectImportTargets(v, targets); |
| 67 | ++ for (const target of targets) { |
| 68 | ++ if (!target || |
| 69 | ++ target.startsWith("./") || |
| 70 | ++ target.startsWith("../") || |
| 71 | ++ target.startsWith("/") || |
| 72 | ++ target.startsWith("#")) |
| 73 | ++ continue; |
| 74 | ++ const parts = target.split("/"); |
| 75 | ++ const targetPkg = parts[0].startsWith("@") |
| 76 | ++ ? `${parts[0]}/${parts[1]}` |
| 77 | ++ : parts[0]; |
| 78 | ++ if (!targetPkg) |
| 79 | ++ continue; |
| 80 | ++ let targetPkgJson; |
| 81 | ++ try { |
| 82 | ++ targetPkgJson = consumerRequire.resolve(`${targetPkg}/package.json`); |
| 83 | ++ } |
| 84 | ++ catch { |
| 85 | ++ logger.debug(`imports-remap: could not resolve ${targetPkg} from ${realConsumerDir}`); |
| 86 | ++ continue; |
| 87 | ++ } |
| 88 | ++ const targetSrcDir = path.dirname(targetPkgJson); |
| 89 | ++ const targetDstDir = path.join(dstNodeModules, targetPkg); |
| 90 | ++ const walk = (src, dst) => { |
| 91 | ++ let entries; |
| 92 | ++ try { |
| 93 | ++ entries = readdirSync(src, { withFileTypes: true }); |
| 94 | ++ } |
| 95 | ++ catch { |
| 96 | ++ return; |
| 97 | ++ } |
| 98 | ++ for (const entry of entries) { |
| 99 | ++ const srcEntry = path.join(src, entry.name); |
| 100 | ++ const dstEntry = path.join(dst, entry.name); |
| 101 | ++ if (entry.isDirectory()) { |
| 102 | ++ if (entry.name === "node_modules") |
| 103 | ++ continue; |
| 104 | ++ walk(srcEntry, dstEntry); |
| 105 | ++ } |
| 106 | ++ else if (entry.isFile()) { |
| 107 | ++ if (filesToCopy.has(srcEntry)) |
| 108 | ++ continue; |
| 109 | ++ filesToCopy.set(srcEntry, dstEntry); |
| 110 | ++ if (srcEntry.endsWith("/package.json")) |
| 111 | ++ pending.push([srcEntry, dstEntry]); |
| 112 | ++ } |
| 113 | ++ } |
| 114 | ++ }; |
| 115 | ++ walk(targetSrcDir, targetDstDir); |
| 116 | ++ } |
| 117 | ++ } |
| 118 | ++} |
| 119 | + function copyPatchFile(outputDir) { |
| 120 | + const patchFile = path.join(__dirname, "patch", "patchedAsyncStorage.js"); |
| 121 | + const outputPatchFile = path.join(outputDir, "patchedAsyncStorage.cjs"); |
| 122 | +@@ -192,6 +298,12 @@ File ${serverPath} does not exist |
| 123 | + routes.forEach((route) => { |
| 124 | + computeCopyFilesForPage(route); |
| 125 | + }); |
| 126 | ++ // Augment traced files with targets of `package.json#imports` subpath remaps. |
| 127 | ++ // Next's NFT tracer does not follow the `imports` field, so packages that are |
| 128 | ++ // only reachable via remaps (e.g. @mathjax/src's "#mhchem/*" → "mhchemparser/esm/*") |
| 129 | ++ // are missing from the trace. Scan every traced package.json for an `imports` |
| 130 | ++ // field and pull in any bare-specifier remap targets from source. |
| 131 | ++ augmentWithImportsRemaps(filesToCopy, buildOutputPath); |
| 132 | + // Only files that are actually copied |
| 133 | + const tracedFiles = []; |
| 134 | + const erroredFiles = []; |
0 commit comments