UNPKG

vite-plugin-react-server

Version:
97 lines (94 loc) 12.7 kB
/** * vite-plugin-react-server * Copyright (c) Nico Brinkkemper * MIT License */ import { transformWithEsbuild } from 'vite'; import { writeFile } from 'node:fs/promises'; import { join, sep } from 'node:path'; function filePreserverPlugin(fileName) { const sources = []; const pluginName = typeof fileName === "string" ? fileName : fileName.slice(3).join("-"); let outDir = "dist"; let root = process.cwd(); let esbuildOptions = { jsxDev: false, supported: { "import-meta": true }, target: "esnext", format: "esm" }; const shouldPreserve = Array.isArray(fileName) ? (id) => fileName.some((f) => id.includes(f)) : (id) => id.includes(fileName); return [ { name: `vite:preserver-${pluginName}:post`, enforce: "post", apply: "build", async transform(_code, id) { if (!shouldPreserve(id)) return; const normalId = id.replace(root + sep, ""); const found = sources.findIndex((s) => s.id === normalId); if (found === -1) { throw new Error(`Source not registered by pre hook for ${id}`); } return { code: sources[found].transformedCode, map: sources[found].map, id: sources[found].id }; }, async writeBundle(_options, bundle) { if (sources.length === 0) return; const entries = Object.entries(bundle); const mapEntries = entries.filter( (entry) => { return entry[1].fileName.endsWith(".map") && shouldPreserve(entry[1].fileName); } ); if (mapEntries.length === 0) { return; } for (const source of sources) { for (const [fileName2, outputAsset] of mapEntries) { const ourMap = source.map; const path = join(root, outDir, fileName2); if (outputAsset.source !== ourMap) { await writeFile(path, ourMap); } } } } }, { name: `vite:preserver-${pluginName}:pre`, apply: "build", enforce: "pre", configResolved(config) { outDir = config.build.outDir; root = config.root; esbuildOptions = config.esbuild || esbuildOptions; }, async transform(code, id) { if (!shouldPreserve(id)) return; const found = sources.find((s) => s.id === id); if (found) { throw new Error(`Source already exists for ${id}`); } const result = await transformWithEsbuild(code, id, esbuildOptions); const source = { id: id.replace(root + sep, ""), originalCode: code, transformedCode: result.code, map: JSON.stringify(result.map) }; sources.push(source); return { id: source.id, code: source.transformedCode, map: source.map }; } } ]; } export { filePreserverPlugin }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vZmlsZS1wcmVzZXJ2ZXIvcGx1Z2luLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgT3V0cHV0QXNzZXQgfSBmcm9tIFwicm9sbHVwXCI7XG5pbXBvcnQgdHlwZSB7IEVTQnVpbGRPcHRpb25zLCBQbHVnaW4gYXMgVml0ZVBsdWdpbiB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgeyB0cmFuc2Zvcm1XaXRoRXNidWlsZCB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgeyB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgam9pbiwgc2VwIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuLyoqXG4gKiBCdW5kbGluZyB3aXRoIHZpdGUgbWF5IGhhdmUgc29tZSBzaWRlIGVmZmVjdHMsIHRoaXMgcGx1Z2luIGlzIGEgd29ya2Fyb3VuZCB0byBwcmV2ZW50XG4gKiB0aGUgc2lkZSBlZmZlY3RzIGZyb20gaGFwcGVuaW5nIHRvIHRoZSBmaWxlcyB3ZSB3YW50IHRvIHByZXNlcnZlLiBJdCdzIHVzZWQgYXMgYSBwbHVnaW5cbiAqIHRvIGJ1aWxkIHRoaXMgcGx1Z2luLCBidXQgeW91IGNhbiBhbHNvIHVzZSBpdCBhcyBhIHN0YW5kYWxvbmUgcGx1Z2luIGZvciB5b3VyIHByb2plY3RzIHRvIGhhdmVcbiAqIHRoZSBzYW1lIGVmZmVjdC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0c3hcbiAqIGltcG9ydCB7IGZpbGVQcmVzZXJ2ZXJQbHVnaW4gfSBmcm9tIFwidml0ZS1wbHVnaW4tcmVhY3Qtc2VydmVyL2ZpbGUtcHJlc2VydmVyXCI7XG4gKlxuICogZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAqICAgcGx1Z2luczogW2ZpbGVQcmVzZXJ2ZXJQbHVnaW4oXCJ1dGlscy9lbnZcIildLCAvLyBkb24ndCBpbmNsdWRlIHRoZSBleHRlbnNpb25cbiAqIH0pO1xuICogYGBgXG4gKiBUaGUgdHlwZXNjcmlwdCBmaWxlIHdpbGwgbm90IGJlIHRyYW5zZm9ybWVkIGJ5IHZpdGUsIG9ubHkgYnkgZXNidWlsZCwgc28geW91IGNhbiBwcmVzZXJ2ZSB5b3VyIGltcG9ydC5tZXRhLmVudlxuICogYW5kIHVzZSBpdCBpbiB5b3VyIGNsaWVudCBib3VuZGFyeSBmaWxlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGVQcmVzZXJ2ZXJQbHVnaW4oZmlsZU5hbWU6IHN0cmluZyB8IHN0cmluZ1tdKTogVml0ZVBsdWdpbltdIHtcbiAgY29uc3Qgc291cmNlczoge1xuICAgIGlkOiBzdHJpbmc7XG4gICAgb3JpZ2luYWxDb2RlOiBzdHJpbmc7XG4gICAgdHJhbnNmb3JtZWRDb2RlOiBzdHJpbmc7XG4gICAgbWFwOiBzdHJpbmc7XG4gIH1bXSA9IFtdO1xuICBjb25zdCBwbHVnaW5OYW1lID1cbiAgICB0eXBlb2YgZmlsZU5hbWUgPT09IFwic3RyaW5nXCIgPyBmaWxlTmFtZSA6IGZpbGVOYW1lLnNsaWNlKDMpLmpvaW4oXCItXCIpO1xuICBsZXQgb3V0RGlyOiBzdHJpbmcgPSBcImRpc3RcIjtcbiAgbGV0IHJvb3Q6IHN0cmluZyA9IHByb2Nlc3MuY3dkKCk7XG4gIGxldCBlc2J1aWxkT3B0aW9uczogRVNCdWlsZE9wdGlvbnMgPSB7XG4gICAganN4RGV2OiBmYWxzZSxcbiAgICBzdXBwb3J0ZWQ6IHsgXCJpbXBvcnQtbWV0YVwiOiB0cnVlIH0sXG4gICAgdGFyZ2V0OiBcImVzbmV4dFwiLFxuICAgIGZvcm1hdDogXCJlc21cIixcbiAgfTtcbiAgY29uc3Qgc2hvdWxkUHJlc2VydmUgPSBBcnJheS5pc0FycmF5KGZpbGVOYW1lKVxuICAgID8gKGlkOiBzdHJpbmcpID0+IGZpbGVOYW1lLnNvbWUoKGYpID0+IGlkLmluY2x1ZGVzKGYpKVxuICAgIDogKGlkOiBzdHJpbmcpID0+IGlkLmluY2x1ZGVzKGZpbGVOYW1lKTtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBuYW1lOiBgdml0ZTpwcmVzZXJ2ZXItJHtwbHVnaW5OYW1lfTpwb3N0YCxcbiAgICAgIGVuZm9yY2U6IFwicG9zdFwiLFxuICAgICAgYXBwbHk6IFwiYnVpbGRcIixcbiAgICAgIGFzeW5jIHRyYW5zZm9ybShfY29kZTogc3RyaW5nLCBpZDogc3RyaW5nKSB7XG4gICAgICAgIGlmICghc2hvdWxkUHJlc2VydmUoaWQpKSByZXR1cm47XG4gICAgICAgIGNvbnN0IG5vcm1hbElkID0gaWQucmVwbGFjZShyb290ICsgc2VwLCBcIlwiKTtcbiAgICAgICAgY29uc3QgZm91bmQgPSBzb3VyY2VzLmZpbmRJbmRleCgocykgPT4gcy5pZCA9PT0gbm9ybWFsSWQpO1xuICAgICAgICBpZiAoZm91bmQgPT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTb3VyY2Ugbm90IHJlZ2lzdGVyZWQgYnkgcHJlIGhvb2sgZm9yICR7aWR9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb2RlOiBzb3VyY2VzW2ZvdW5kXS50cmFuc2Zvcm1lZENvZGUsXG4gICAgICAgICAgbWFwOiBzb3VyY2VzW2ZvdW5kXS5tYXAsXG4gICAgICAgICAgaWQ6IHNvdXJjZXNbZm91bmRdLmlkLFxuICAgICAgICB9O1xuICAgICAgfSxcbiAgICAgIGFzeW5jIHdyaXRlQnVuZGxlKF9vcHRpb25zLCBidW5kbGUpIHtcbiAgICAgICAgaWYgKHNvdXJjZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGVudHJpZXMgPSBPYmplY3QuZW50cmllcyhidW5kbGUpO1xuICAgICAgICBjb25zdCBtYXBFbnRyaWVzID0gZW50cmllcy5maWx0ZXIoXG4gICAgICAgICAgKGVudHJ5KTogZW50cnkgaXMgW3N0cmluZywgT3V0cHV0QXNzZXRdID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIGVudHJ5WzFdLmZpbGVOYW1lLmVuZHNXaXRoKFwiLm1hcFwiKSAmJlxuICAgICAgICAgICAgICBzaG91bGRQcmVzZXJ2ZShlbnRyeVsxXS5maWxlTmFtZSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBpZiAobWFwRW50cmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXZlbiB0aG91Z2ggd2UncmUgcmV0dXJuaW5nIHRoZSBuZXcgc291cmNlIG1hcCwgaXQgbWlnaHQganVzdCB3cml0ZSA7Ozs7IHRvIHRoZSBmaWxlXG4gICAgICAgIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IFtmaWxlTmFtZSwgb3V0cHV0QXNzZXRdIG9mIG1hcEVudHJpZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG91ck1hcCA9IHNvdXJjZS5tYXA7XG4gICAgICAgICAgICBjb25zdCBwYXRoID0gam9pbihyb290LCBvdXREaXIsIGZpbGVOYW1lKTtcbiAgICAgICAgICAgIGlmIChvdXRwdXRBc3NldC5zb3VyY2UgIT09IG91ck1hcCkge1xuICAgICAgICAgICAgICBhd2FpdCB3cml0ZUZpbGUocGF0aCwgb3VyTWFwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBgdml0ZTpwcmVzZXJ2ZXItJHtwbHVnaW5OYW1lfTpwcmVgLFxuICAgICAgYXBwbHk6IFwiYnVpbGRcIixcbiAgICAgIGVuZm9yY2U6IFwicHJlXCIsXG4gICAgICBjb25maWdSZXNvbHZlZChjb25maWcpIHtcbiAgICAgICAgb3V0RGlyID0gY29uZmlnLmJ1aWxkLm91dERpcjtcbiAgICAgICAgcm9vdCA9IGNvbmZpZy5yb290O1xuICAgICAgICBlc2J1aWxkT3B0aW9ucyA9IGNvbmZpZy5lc2J1aWxkIHx8IGVzYnVpbGRPcHRpb25zO1xuICAgICAgfSxcbiAgICAgIGFzeW5jIHRyYW5zZm9ybShjb2RlOiBzdHJpbmcsIGlkOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCFzaG91bGRQcmVzZXJ2ZShpZCkpIHJldHVybjtcbiAgICAgICAgY29uc3QgZm91bmQgPSBzb3VyY2VzLmZpbmQoKHMpID0+IHMuaWQgPT09IGlkKTtcbiAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTb3VyY2UgYWxyZWFkeSBleGlzdHMgZm9yICR7aWR9YCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdHJhbnNmb3JtV2l0aEVzYnVpbGQoY29kZSwgaWQsIGVzYnVpbGRPcHRpb25zKTtcbiAgICAgICAgY29uc3Qgc291cmNlID0ge1xuICAgICAgICAgIGlkOiBpZC5yZXBsYWNlKHJvb3QgKyBzZXAsIFwiXCIpLFxuICAgICAgICAgIG9yaWdpbmFsQ29kZTogY29kZSxcbiAgICAgICAgICB0cmFuc2Zvcm1lZENvZGU6IHJlc3VsdC5jb2RlLFxuICAgICAgICAgIG1hcDogSlNPTi5zdHJpbmdpZnkocmVzdWx0Lm1hcCksXG4gICAgICAgIH07XG4gICAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGlkOiBzb3VyY2UuaWQsXG4gICAgICAgICAgY29kZTogc291cmNlLnRyYW5zZm9ybWVkQ29kZSxcbiAgICAgICAgICBtYXA6IHNvdXJjZS5tYXAsXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgIH0sXG4gIF07XG59XG4iXSwibmFtZXMiOlsiZmlsZU5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQXFCTyxTQUFTLG9CQUFvQixRQUEyQyxFQUFBO0FBQzdFLEVBQUEsTUFBTSxVQUtBLEVBQUM7QUFDUCxFQUFNLE1BQUEsVUFBQSxHQUNKLE9BQU8sUUFBQSxLQUFhLFFBQVcsR0FBQSxRQUFBLEdBQVcsU0FBUyxLQUFNLENBQUEsQ0FBQyxDQUFFLENBQUEsSUFBQSxDQUFLLEdBQUcsQ0FB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