UNPKG

@vitejs/plugin-rsc

Version:
110 lines (107 loc) 4.17 kB
import { t as createDebug } from "./dist-BRSdGcl7.js"; import { n as parseIdQuery } from "./shared-AtH_QTi7.js"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; import * as esModuleLexer from "es-module-lexer"; import MagicString from "magic-string"; import { parseAstAsync } from "vite"; import { findClosestPkgJsonPath } from "vitefu"; import { walk } from "estree-walker"; import { analyze } from "periscopic"; //#region src/transforms/cjs.ts const CJS_INTEROP_HELPER = `function __cjs_interop__(m) { return m.__cjs_module_runner_transform ? m.default : m; }`; function transformCjsToEsm(code, ast, options) { const output = new MagicString(code); const analyzed = analyze(ast); const parentNodes = []; const hoistedCodes = []; let hoistIndex = 0; walk(ast, { enter(node) { parentNodes.push(node); if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "require" && node.arguments.length === 1) { let isTopLevel = true; for (const parent of parentNodes) { if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration" || parent.type === "ArrowFunctionExpression") isTopLevel = false; const scope = analyzed.map.get(parent); if (scope && scope.declarations.has("require")) return; } if (isTopLevel) { output.update(node.start, node.callee.end, "(__cjs_interop__(await import"); output.appendRight(node.end, "))"); } else { const hoisted = `__cjs_to_esm_hoist_${hoistIndex}`; const importee = code.slice(node.arguments[0].start, node.arguments[0].end); hoistedCodes.push(`const ${hoisted} = __cjs_interop__(await import(${importee}));\n`); output.update(node.start, node.end, hoisted); hoistIndex++; } } }, leave() { parentNodes.pop(); } }); for (const hoisted of hoistedCodes.reverse()) output.prepend(hoisted); if (output.hasChanged()) output.prepend(`${CJS_INTEROP_HELPER}\n`); output.prepend(`let exports = {}; const module = { exports };\n`); const __filename = fileURLToPath(pathToFileURL(options.id).href); const __dirname = path.dirname(__filename); output.prepend(`let __filename = ${JSON.stringify(__filename)}; let __dirname = ${JSON.stringify(__dirname)};\n`); output.append(` ;__vite_ssr_exportAll__(module.exports); export default module.exports; export const __cjs_module_runner_transform = true; `); return { output }; } //#endregion //#region src/plugins/cjs.ts const debug = createDebug("vite-rsc:cjs"); function cjsModuleRunnerPlugin() { const warnedPackages = /* @__PURE__ */ new Set(); return [{ name: "cjs-module-runner-transform", apply: "serve", applyToEnvironment: (env) => env.config.dev.moduleRunnerTransform, async transform(code, id) { if (id.includes("/node_modules/") && !id.startsWith(this.environment.config.cacheDir) && /\b(require|exports)\b/.test(code)) { id = parseIdQuery(id).filename; if (!/\.[cm]?js$/.test(id)) return; if (id.endsWith(".mjs")) return; if (id.endsWith(".js")) { const pkgJsonPath = await findClosestPkgJsonPath(path.dirname(id)); if (pkgJsonPath) { if (JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8")).type === "module") return; } } const [, , , hasModuleSyntax] = esModuleLexer.parse(code); if (hasModuleSyntax) return; const packageKey = extractPackageKey(id); if (!warnedPackages.has(packageKey)) { debug(`non-optimized CJS dependency in '${this.environment.name}' environment: ${id}`); warnedPackages.add(packageKey); } const output = transformCjsToEsm(code, await parseAstAsync(code), { id }).output; return { code: output.toString(), map: output.generateMap({ hires: "boundary" }) }; } } }]; } function extractPackageKey(id) { const yarnMatch = id.match(/\/.yarn\/cache\/([^/]+)/); if (yarnMatch) return yarnMatch[1]; if (id.includes("/node_modules")) { id = id.split("/node_modules/").at(-1); let [x, y] = id.split("/"); if (x.startsWith("@")) return `${x}/${y}`; return x; } return id; } //#endregion export { cjsModuleRunnerPlugin as t };