UNPKG

vite-plugin-react-server

Version:
127 lines (124 loc) 3.77 kB
/** * vite-plugin-react-server * Copyright (c) Nico Brinkkemper * MIT License */ import { DEFAULT_CONFIG } from '../config/defaults.js'; import { basename } from 'path'; const REACT_DIRECTIVES = /* @__PURE__ */ new Set(["use client", "use server"]); function createSourceMap(id, code, mappings) { return { version: 3, file: basename(id), sources: [id], sourcesContent: [code], names: [], mappings, sourceRoot: "" }; } function removeRanges(code, ranges) { ranges.sort((a, b) => b.start - a.start); let result = code; for (const range of ranges) { result = result.slice(0, range.start) + result.slice(range.end); } return result; } function countLines(str) { let count = 1; for (let i = 0; i < str.length; i++) { if (str[i] === "\n") count++; } return count; } function reactPreservePlugin(_options) { const meta = {}; return { name: "vite-plugin-react-server:preserve-directives", enforce: "post", transform: { order: "post", // Ensure this runs last in transform phase handler(code, id) { if (id.includes("node_modules") || id.includes("vite/dist") || !id.match(DEFAULT_CONFIG.FILE_REGEX)) { return null; } let ast; try { ast = this.parse(code, { allowReturnOutsideFunction: true, jsx: true }); } catch (e) { console.warn(`[PreservePlugin] Failed to parse ${id}`, e); return null; } if (ast.type !== "Program") { return null; } const rangesToRemove = []; let hasChanged = false; let mappings = "AAAA"; for (const node of ast.body) { if (node.type !== "ExpressionStatement") { break; } let directive = null; if ("directive" in node) { directive = node.directive; } else if (node.expression.type === "Literal" && typeof node.expression.value === "string" && REACT_DIRECTIVES.has(node.expression.value)) { directive = node.expression.value; } if (directive && "start" in node && "end" in node) { meta[id] ||= /* @__PURE__ */ new Set(); meta[id].add(directive); rangesToRemove.push({ start: node.start, end: node.end }); hasChanged = true; const removedLines = code.slice(node.start, node.end).split("\n").length - 1; for (let i = 0; i < removedLines; i++) { mappings += ";AACA"; } } } if (!hasChanged) { return null; } const newCode = removeRanges(code, rangesToRemove); const sourceMap = createSourceMap(id, code, mappings); return { code: newCode, map: sourceMap, meta: { directives: Array.from(meta[id] || []) } }; } }, renderChunk(code, chunk) { const chunkDirectives = /* @__PURE__ */ new Set(); for (const id of chunk.moduleIds) { if (meta[id]) { meta[id].forEach((d) => chunkDirectives.add(d)); } } if (chunkDirectives.size) { const directivesCode = Array.from(chunkDirectives).map((d) => `"${d}";`).join("\n") + "\n"; const newCode = directivesCode + code; const lineCount = countLines(directivesCode); const mappings = "AAAA" + ";AACA".repeat(lineCount - 1); const sourceMap = createSourceMap(chunk.fileName, code, mappings); return { code: newCode, map: sourceMap }; } return null; } }; } export { reactPreservePlugin }; //# sourceMappingURL=plugin.js.map