UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

147 lines (146 loc) 4.91 kB
import { VIRTUAL_SSR_CSS_ENTRY, VIRTUAL_SSR_CSS_HREF } from "../../constants.native.js"; function SSRCSSPlugin(pluginOpts) { var server; return { name: `one-plugin-ssr-css`, apply: "serve", configureServer(server_) { server = server_; server.middlewares.use(async function (req, res, next) { var _req_url; if ((_req_url = req.url) === null || _req_url === void 0 ? void 0 : _req_url.includes(VIRTUAL_SSR_CSS_HREF)) { invalidateModule(server, "\0" + VIRTUAL_SSR_CSS_ENTRY + "?direct"); var code = await collectStyle(server, pluginOpts.entries); res.setHeader("Content-Type", "text/css"); res.setHeader("Cache-Control", "no-store"); res.setHeader("Vary", "*"); res.write(code); res.end(); return; } next(); }); }, // virtual module // (use `startsWith` since Vite adds `?direct` for raw css request) resolveId(source, _importer, _options) { return source.startsWith(VIRTUAL_SSR_CSS_ENTRY) ? "\0" + source : void 0; }, async load(id, _options) { if (id.startsWith("\0" + VIRTUAL_SSR_CSS_ENTRY)) { var url = new URL(id.slice(1), "https://test.local"); var code = await collectStyle(server, pluginOpts.entries); if (!url.searchParams.has("direct")) { code = `export default ${JSON.stringify(code)}`; } return code; } return; }, // also expose via transformIndexHtml transformIndexHtml: { handler: async function () { return [{ tag: "link", // prepend so SSR CSS comes BEFORE individual style tags injected by JS // this ensures individual styles (later in DOM) win in CSS cascade injectTo: "head-prepend", attrs: { rel: "stylesheet", href: VIRTUAL_SSR_CSS_HREF, "data-ssr-css": true } }, { tag: "script", injectTo: "head", attrs: { type: "module" }, children: (/* js */ ` import { createHotContext } from "/@vite/client"; const hot = createHotContext("/__clear_ssr_css"); hot.on("vite:beforeUpdate", () => { document .querySelectorAll("[data-ssr-css]") .forEach(node => node.remove()); }); `) }]; } } }; } function invalidateModule(server, id) { var mod = server.moduleGraph.getModuleById(id); if (mod) { server.moduleGraph.invalidateModule(mod); } } async function collectStyle(server, entries) { var { transform } = await import("lightningcss"); var urls = await collectStyleUrls(server, entries); var codes = await Promise.all(urls.map(async function (url) { var res = await server.transformRequest(url + "?direct"); var code = (res === null || res === void 0 ? void 0 : res.code) || ""; var prefix = `/* [collectStyle] ${url} */`; try { var buffer2 = Buffer.from(code); var codeOut2 = new Uint8Array(buffer2.buffer, buffer2.byteOffset, buffer2.byteLength); var processed = transform({ filename: "code.css", code: codeOut2, ...server.config.css.lightningcss }).code.toString(); return [prefix, processed]; } catch (err) { console.error(` [one] Error post-processing CSS, leaving un-processed: ${err}`); return [prefix, code]; } })); var out = codes.flat().filter(Boolean).join("\n\n"); try { var buffer = Buffer.from(out); var codeOut = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); out = transform({ filename: "code.css", code: codeOut, ...server.config.css.lightningcss }).code.toString(); } catch (err) { console.error(` [one] Error post-processing merged CSS, leaving un-processed`); } return out; } async function collectStyleUrls(server, entries) { var visited = /* @__PURE__ */new Set(); async function traverse(url) { if (url.includes(".server.")) return; var [, id] = await server.moduleGraph.resolveUrl(url); if (visited.has(id)) { return; } visited.add(id); var mod = server.moduleGraph.getModuleById(id); if (!mod) { return; } await Promise.all([...mod.importedModules].map(function (childMod) { return traverse(childMod.url); })); } await Promise.all(entries.map(function (e) { return server.transformRequest(e); })); await Promise.all(entries.map(function (url) { return traverse(url); })); return [...visited].filter(function (url) { return url.match(CSS_LANGS_RE); }); } var CSS_LANGS_RE = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/; export { SSRCSSPlugin, collectStyle }; //# sourceMappingURL=SSRCSSPlugin.native.js.map