UNPKG

vite-plugin-react18-pages

Version:

<p> <a href="https://www.npmjs.com/package/vite-plugin-react-pages" target="_blank" rel="noopener"><img src="https://img.shields.io/npm/v/vite-plugin-react-pages.svg" alt="npm package" /></a> </p>

187 lines 7.97 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ssrBuild = void 0; const fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const vite_1 = require("vite"); const constants_1 = require("../constants"); async function ssrBuild(viteConfig, ssrConfig, argv) { var _a, _b, _c; // ssr build should not use hash router // if (viteOptions?.define?.['__HASH_ROUTER__']) // viteOptions!.define!['__HASH_ROUTER__'] = false const root = viteConfig.root; let outDir = (_b = (_a = viteConfig.build) === null || _a === void 0 ? void 0 : _a.outDir) !== null && _b !== void 0 ? _b : "dist"; outDir = path.resolve(root, outDir); await fs.emptyDir(outDir); const ssrOutDir = path.join(outDir, "ssr-tmp"); const clientOutDir = path.join(outDir, "client-tmp"); console.log("\n\npreparing vite pages ssr bundle..."); const ssrOutput = await (0, vite_1.build)({ root, configFile: viteConfig.configFile, build: { ssr: true, cssCodeSplit: false, rollupOptions: { input: path.join(constants_1.CLIENT_PATH, "ssr", "serverRender.js"), preserveEntrySignatures: "allow-extension", output: { format: "cjs", exports: "named", entryFileNames: "[name].js", }, }, outDir: ssrOutDir, minify: false, }, // @ts-ignore ssr: { external: ["react", "react-router-dom", "react-dom", "react-dom/server"], noExternal: [ // TODO: remove this "vite-pages-theme-basic", "vite-plugin-react18-pages", "vite-plugin-react18-pages/client", ], }, }); console.log("\n\nrendering html..."); const { renderToString, ssrData } = require(path.join(ssrOutDir, "serverRender.js")); const pagePaths = Object.keys(ssrData); console.log("\n\npreparing vite pages client bundle..."); const _clientResult = await (0, vite_1.build)({ root, configFile: viteConfig.configFile, build: { cssCodeSplit: false, rollupOptions: { input: path.join(constants_1.CLIENT_PATH, "ssr", "clientRender.js"), preserveEntrySignatures: "allow-extension", }, assetsDir: "assets", outDir: clientOutDir, }, }); let clientResult; if (Array.isArray(_clientResult)) { if (_clientResult.length !== 1) throw new Error(`expect viteBuild to have only one BuildResult`); clientResult = _clientResult[0]; } else { clientResult = _clientResult; } const entryChunk = (() => { const _entryChunks = clientResult.output.filter((chunkOrAsset) => { return chunkOrAsset.type === "chunk" && chunkOrAsset.isEntry; }); if (_entryChunks.length !== 1) { throw new Error(`Expect one entryChunk. Got ${_entryChunks.length}.`); } return _entryChunks[0]; })(); const cssChunks = clientResult.output.filter((chunk) => { return chunk.type === "asset" && chunk.fileName.endsWith(".css"); }); const basePath = (_c = viteConfig.base) !== null && _c !== void 0 ? _c : "/"; const htmlCode = await fs.readFile(path.join(root, "index.html"), "utf-8"); const RootElementInjectPoint = '<div id="root"></div>'; if (!htmlCode.includes(RootElementInjectPoint)) { throw new Error(`Your index.html should contain the RootElementInjectPoint: "${RootElementInjectPoint}" (it must appear exactly as-is)`); } const EntryModuleInjectPoint = '<script type="module" src="/@pages-infra/main.js"></script>'; if (!htmlCode.includes(EntryModuleInjectPoint)) { throw new Error(`Your index.html should contain EntryModuleInjectPoint: "${EntryModuleInjectPoint}" (it must appear exactly as-is)`); } const CSSInjectPoint = "</head>"; if (!htmlCode.includes(CSSInjectPoint)) { throw new Error(`Your index.html should contain CSSInjectPoint: "${CSSInjectPoint}" (it must appear exactly as-is)`); } await Promise.all(pagePaths.map(async (pagePath) => { // currently not support pages with path params // .e.g /users/:userId if (pagePath.match(/\/:\w/)) return; const html = renderHTML(pagePath); // TODO: injectPreload // preload data module for this page // html = injectPreload(html, "path/to/page/data") const writePath = path.join(clientOutDir, pagePath.replace(/^\//, ""), "index.html"); await fs.ensureDir(path.dirname(writePath)); await fs.writeFile(writePath, html); if (pagePath !== "/") { // should write to both /pagePath/index.html and /pagePath.html const writePath2 = path.join(clientOutDir, pagePath.replace(/^\//, "") + ".html"); await fs.ensureDir(path.dirname(writePath2)); await fs.writeFile(writePath2, html); } })); const html404Path = path.join(clientOutDir, "404.html"); // pass in a pagePath that won't match any defined page // so the render result will be 404 page const html404 = renderHTML("/internal-404-page"); await fs.writeFile(html404Path, html404); // move 404 page to `/` if `/` doesn't exists if (!pagePaths.includes("/")) { await fs.copy(html404Path, path.join(clientOutDir, "index.html")); } await fs.copy(clientOutDir, outDir); await fs.remove(clientOutDir); await fs.remove(ssrOutDir); console.log("vite pages ssr build finished successfully."); return; function renderHTML(pagePath) { const ssrContent = renderToString(pagePath); const ssrInfo = { routePath: pagePath, }; let html = htmlCode.replace(RootElementInjectPoint, // let client know the current ssr page `<script>window._vitePagesSSR=${JSON.stringify(ssrInfo)};</script> <div id="root">${ssrContent}</div>`); const cssInject = cssChunks .map((cssChunk) => { return `<link rel="stylesheet" href="${basePath}${cssChunk.fileName}" />`; }) .join("\n"); html = html.replace(CSSInjectPoint, `${cssInject} ${CSSInjectPoint}`); html = html.replace(EntryModuleInjectPoint, `<script type="module" src="${basePath}${entryChunk.fileName}"></script>`); return html; } } exports.ssrBuild = ssrBuild; const injectPreload = (html, filePath) => { const tag = `<link rel="modulepreload" href="${filePath}" />`; if (/<\/head>/.test(html)) { return html.replace(/<\/head>/, `${tag}\n</head>`); } else { return tag + "\n" + html; } }; //# sourceMappingURL=index.js.map