@bdocs/ssg 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./state-OWuAHBHy.cjs`);let n=require(`react/jsx-runtime`),r=require(`node:module`),i=require(`node:path`),a=require(`fs-extra`);a=e.t(a,1);let o=require(`jsdom`),s=require(`kolorist`),c=require(`vite`),l=require(`node:events`),u=require(`node:stream`),d=require(`react-dom/server`);d=e.t(d);const f=/import\("([^)]+)"\)/g;async function p({routes:e,locationArg:t,base:n,serverManifest:r,manifest:i,ssrManifest:a}){let{matchRoutes:o}=await import(`react-router-dom`),s=o([...e],t,n),c=s?.map(e=>e.route.entry).filter(Boolean)??[],l=new Set;s?.forEach(e=>{let t=``;e.route.lazy&&(t+=e.route.lazy.toString()),e.route.Component?._payload?._result&&(t+=e.route.Component._payload._result.toString());let n=t.matchAll(f);for(let e of n)l.add(e[1].split(`/`).at(-1)??``)});let u=new Set;c.forEach(e=>u.add(e));let d=[...Object.entries(r)];l.forEach(e=>{let t=d.find(([t,n])=>n.file.endsWith(e));t&&u.add(t[0])});let p=m(i,u),h=new Set;return Array.from(p).forEach(e=>{(a[e]||[]).forEach(e=>{h.add(e)})}),h}function m(e,t){let n=new Set;if(!t)return n;for(let r of t)h(e,r,n);return n}function h(e,t,n=new Set){return t?(n.add(t),e[t]?.dynamicImports?.forEach(t=>{h(e,t,n)}),n):n}async function g(e,t={}){try{let n=await import(`beasties`);return new(n.default||n)({path:e,logLevel:`warn`,external:!0,inlineFonts:!0,preloadFonts:!0,...t})}catch{}try{let n=await import(`critters`),r=n.default||n;return console.warn("`critters` is deprecated. Please use `beasties` instead."),new r({path:e,logLevel:`warn`,external:!0,inlineFonts:!0,preloadFonts:!0,...t})}catch{return}}const _=`/* SCRIPT_COMMENT_PLACEHOLDER */`;async function v({rootContainerId:e,indexHTML:t,appHTML:n,metaAttributes:r,bodyAttributes:i,htmlAttributes:a,initialState:o}){let s=o?`\n<script>window.__INITIAL_STATE__=${o}<\/script>`:``,c=`\n<script>${_}<\/script>`,l=`<head>`,u=r.join(``);t=t.replace(l,l+u);let d=`<body`;t=t.replace(d,`${d} ${i}`);let f=`<html`;t=t.replace(f,`${f} ${a}`);let p=`<div id="${e}"></div>`;if(t.includes(p))return t.replace(p,`<div id="${e}" data-server-rendered="true">${n}</div>${s}${c}`);let m=await import(`html5parser`),h=m.parse(t),g;if(m.walk(h,{enter:r=>{if(!g&&r?.type===m.SyntaxKind.Tag&&Array.isArray(r.attributes)&&r.attributes.length>0&&r.attributes.some(t=>t.name.value===`id`&&t.value?.value===e)){let e=[...r.attributes.map(({name:{value:e},value:t})=>`${e}="${t.value}"`)].join(` `),i=t.slice(0,r.start),a=t.slice(r.end);g=`${i}<${r.name} ${e} data-server-rendered="true">${n}</${r.name}>${s}${c}${a}`}}}),!g)throw Error(`Could not find a tag with id="${e}" to replace it with server-side rendered HTML`);return g}async function y(e,t=`index.html`){let[,n]=[...(await a.default.readFile((0,i.join)(e,t),`utf-8`)).matchAll(/<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/gim)].find(e=>{let[t]=e,[,n]=t.match(/.*\stype=(?:'|")?([^>'"\s]+)/i)||[];return n===`module`})||[];return n||`src/main.ts`}function b(e){return`<link rel="stylesheet" href="${e}">`}function x(e,t){let n=new Set;t&&t.forEach(t=>{n.has(t)||(n.add(t),S(e,t))})}function S(e,t){t.endsWith(`.js`)?T(e,{rel:`modulepreload`,crossOrigin:``,href:t}):t.endsWith(`.css`)?T(e,{rel:`stylesheet`,href:t,crossOrigin:``}):t.endsWith(`.woff`)||t.endsWith(`.woff2`)||t.endsWith(`.ttf`)?T(e,{rel:`preload`,as:`font`,type:`font/woff2`,href:t,crossOrigin:``}):(t.endsWith(`.png`)||t.endsWith(`.jpg`)||t.endsWith(`.jpeg`)||t.endsWith(`.webp`)||t.endsWith(`.gif`)||t.endsWith(`.ico`)||t.endsWith(`.svg`))&&T(e,{rel:`preload`,as:`image`,href:t,crossOrigin:``})}function C(e){return e.createElement(`link`)}function w(e,t){let n=Object.keys(t);for(let r of n)e.setAttribute(r,t[r])}function T(e,t){if(e.head.querySelector(`link[href='${t.file}']`))return;let n=C(e);w(n,t),e.head.appendChild(n)}function E(e,t){if(e===!1||e==null)throw console.error(`The following error is a bug in Vite-react-ssg; please open an issue! https://github.com/Daydreamer-riri/vite-react-ssg/issues/new`),Error(t)}function D(e){let t=new Headers;for(let[n,r]of Object.entries(e))if(r)if(Array.isArray(r))for(let e of r)t.append(n,e);else t.set(n,r);return t}function O(e){let t=e.headers.origin&&e.headers.origin!==`null`?e.headers.origin:`http://${e.headers.host}`;E(e.originalUrl,"Expected `nodeReq.originalUrl` to be defined");let n=new URL(e.originalUrl,t),r={method:e.method,headers:D(e.headers)};return new Request(n.href,r)}async function k(e,t){t.statusCode=e.status,t.statusMessage=e.statusText;for(let[n,r]of e.headers)t.setHeader(n,r);if(e.body){let n=e.body,r=u.Readable.from(n);r.pipe(t),await(0,l.once)(r,`end`)}else t.end()}function A(e){let t=new URL(e.url);t.searchParams.delete(`_data`);let n={method:e.method,body:e.body,headers:e.headers,signal:e.signal};return n.body&&(n.duplex=`half`),new Request(t.href,n)}async function j(e){if(!d.renderToPipeableStream)return d.renderToString((0,n.jsx)(n.Fragment,{children:e}));let t=new M,{pipe:r}=d.renderToPipeableStream(e,{onError(e){t.destroy(e)},onAllReady(){r(t)}});return t.getPromise()}var M=class extends u.Writable{constructor(){super(),this._output=``,this._deferred={promise:null,resolve:()=>null,reject:()=>null},this._deferred.promise=new Promise((e,t)=>{this._deferred.resolve=e,this._deferred.reject=t})}_write(e,t,n){this._output+=e.toString(),n()}_destroy(e,t){e instanceof Error?this._deferred.reject(e):t()}end(){return this._deferred.resolve(this._output),this.destroy()}getPromise(){return this._deferred.promise}};function N(e,t,n){let{helmet:r}=t,i=r.htmlAttributes.toString(),a=r.bodyAttributes.toString(),o=r.title.toString();o.split(`>`)[1]===`</title`&&(o=``);let s=[o,r.meta.toString(),r.link.toString(),r.script.toString()],c=n?.toString?.(e)??``;return{htmlAttributes:i,bodyAttributes:a,metaAttributes:s.filter(Boolean),styleTag:c}}const{HelmetProvider:P}=(0,r.createRequire)(require(`url`).pathToFileURL(__filename).href)(`react-helmet-async`);var F=class{constructor(e){this.handleLoader=async(e,n)=>{let{routes:r,base:i}=this.context,{matchRoutes:a}=await import(`react-router-dom`),o=O(e),s=new URL(o.url),c=decodeURIComponent(s.searchParams.get(`_data`)),l=a(t.r([...r],e=>e),{pathname:s.pathname,search:s.search,hash:s.hash,state:null,key:`default`},i);if(!l){n.statusCode=404,n.end(`Route not found: ${c}`);return}let u=l.find(e=>e.route.id===c);if(!u){n.statusCode=404,n.end(`Route not found: ${c}`);return}let d=u.route.loader??await u.route.lazy?.().then(e=>e.loader);if(!d){n.statusCode=200,n.end(`There is no loader for the route: ${c}`);return}await k(await I({loader:d,params:u.params,request:o,routeId:c}),n)},this.context=e}async render(e){let{base:r,routes:i,getStyleCollector:a,routerOptions:o}=this.context,s=`http://localhost${t.s(e)}`,c=new Request(s),l=a?await a():null,u={},d=null,{StaticRouterProvider:f,createStaticHandler:p,createStaticRouter:m}=await import(`react-router-dom`),h=t.r([...i],e=>e),{query:g}=p(h),_=await g(c);if(_ instanceof Response)throw _;d=_;let v=(0,n.jsx)(P,{context:u,children:(0,n.jsx)(f,{router:m(h,d,{future:o.future}),context:d})});l&&(v=l.collect(v));let y=await j(v),{htmlAttributes:b,bodyAttributes:x,metaAttributes:S,styleTag:C}=N(y,u,l);return{appHTML:y,htmlAttributes:b,bodyAttributes:x,metaAttributes:S,styleTag:C,routerContext:d}}};async function I({loader:e,params:t,request:n,routeId:r}){let{json:i}=await import(`react-router-dom`),a=await e({request:A(R(n)),params:t});if(a===void 0)throw Error(`You defined a loader for route "${r}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`);return L(a)?a:i(a)}function L(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.headers==`object`&&e.body!==void 0}function R(e){let t=new URL(e.url),n=t.searchParams.getAll(`index`);t.searchParams.delete(`index`);let r=[];for(let e of n)e&&r.push(e);for(let e of r)t.searchParams.append(`index`,e);let i={method:e.method,body:e.body,headers:e.headers,signal:e.signal};return i.body&&(i.duplex=`half`),new Request(t.href,i)}function ee(e){return new F(e)}var z=`0.0.1`;function B(e,t){console.log(`\n${(0,s.gray)(`[vite-react-ssg]`)} ${(0,s.yellow)(e)}${t?(0,s.blue)(` (${t})`):``}`)}function te(e){return`${(e.length/1024).toFixed(2)} KiB`}async function V(e){if(!e||e.length===0)return{paths:[`/`]};let t=new Set,n=async(e,i=``)=>{i=i.replace(/\/$/g,``);for(let a of e){if(a.lazy){let e=await a.lazy();e&&(a={...a,...e})}let e=a.path;if(e=r(e,i),a.getStaticPaths&&H(e)){let e=await a.getStaticPaths();for(let t of e)t=r(t,i),Array.isArray(a.children)&&await n(a.children,t)}a.index&&!e&&t.add(`/`),Array.isArray(a.children)&&await n(a.children,e)}};return await n(e),{paths:Array.from(t)};function r(e,n){return e!=null&&(e=n&&!e.startsWith(`/`)?`${n}${e?`/${e}`:``}`:e,t.add(e)),e}}async function ne(e,t){return await e.createResolver()(t,e.root)||(t.startsWith(`virtual:`)||t.includes(`\0`)?t:(0,i.join)(e.root,t))}const re=/[:*?]/;function H(e){return e?re.test(e):!1}const U=Number.parseInt(c.version)>=5?[`.vite`]:[];function ie(e){return Number.parseInt(c.version)>=8?{rolldownOptions:e}:{rollupOptions:e}}function ae(e,n){return`static-loader-data${t.s(e===`/`?`/index`:e.endsWith(`/`)?`${e}index`:e)}.${n}.json`}function oe(e,t){return e.filter(e=>!e.includes(`:`)&&!e.includes(`*`))}async function W(e={},n={}){let l=process.env.MODE||process.env.NODE_ENV||e.mode||`production`,u=await(0,c.resolveConfig)(n,`build`,l,l),d=process.cwd(),f=u.root||d,m=Math.random().toString(36).substring(2,12),h=(0,i.join)(f,`.vite-react-ssg-temp`,m),b=u.build.outDir||`dist`,S=u.base,C=Object.assign({},u.ssgOptions||{},e),{script:w=`sync`,mock:T=!1,htmlEntry:E=`index.html`,entry:D=await y(f,E),formatting:O=`none`,includedRoutes:k=oe,onBeforePageRender:A,onPageRendered:j,onFinished:M,dirStyle:N=`flat`,includeAllRoutes:P=!1,format:F=`esm`,concurrency:I=20,rootContainerId:L=`root`}=C,R=C.beastiesOptions??C.crittersOptions??{};a.default.existsSync(h)&&await a.default.remove(h);let z=(0,c.createLogger)(),re=z.warn;z.warn=(e,t)=>{e.includes(`vite:resolve`)&&e.includes(`externalized for browser compatibility`)||re(e,t)},B(`Build for client...`),await(0,c.build)((0,c.mergeConfig)(n,{build:{manifest:!0,ssrManifest:!0,...ie({input:{app:(0,i.join)(f,E||`./index.html`)},onLog(e,t,n){t.message.includes(`react-helmet-async`)||n(e,t)}})},customLogger:z,mode:u.mode,plugins:[{name:`vite-react-ssg:get-oup-dir`,configResolved(e){b=e.build.outDir||`dist`}}]}));let H=()=>{};if(T){let{jsdomGlobal:e}=await Promise.resolve().then(()=>require(`./jsdomGlobal-DIW81D0t.cjs`));H=e()}B(`Build for server...`),process.env.VITE_SSG=`true`;let W=await ne(u,D);await(0,c.build)((0,c.mergeConfig)(n,{build:{ssr:W,manifest:!0,outDir:h,minify:!1,cssCodeSplit:!1,...ie({output:F===`esm`?{entryFileNames:`[name].mjs`,format:`esm`}:{entryFileNames:`[name].cjs`,format:`cjs`},onLog(e,t,n){t.message.includes(`react-helmet-async`)||n(e,t)}})},mode:u.mode}));let le=F===`esm`&&process.platform===`win32`?`file://`:``,G=F===`esm`?`.mjs`:`.cjs`,ue=W.replace(/\0/g,``).replace(`virtual:`,``).replace(/[^a-zA-Z0-9-]/g,`_`),K=le+(0,i.join)(h,(W.includes(`/`)||W.includes(`\\`)?W.split(/[/\\]/).pop().replace(G,``):ue)+G).replace(/\\/g,`/`),de=JSON.parse(await a.default.readFile((0,i.join)(h,...U,`manifest.json`),`utf-8`)),fe=typeof require<`u`?require:(0,r.createRequire)(require(`url`).pathToFileURL(__filename).href),{createRoot:pe,includedRoutes:me}=F===`esm`?await import(K):fe(K),he=me||k,{routes:q}=await pe(!1),{paths:ge}=await V(q),J=P?ge:await he(ge,q||[]);J=oe(J,q||[]),J=Array.from(new Set(J)),B(`Rendering Pages...`,J.length);let Y=R===!1?void 0:await g(b,{publicPath:S,...R});Y&&console.log(`${(0,s.gray)(`[vite-react-ssg]`)} ${(0,s.blue)("Critical CSS generation enabled via `beasties`")}`);let X=(0,i.isAbsolute)(b)?b:(0,i.join)(f,b),_e=JSON.parse(await a.default.readFile((0,i.join)(X,...U,`ssr-manifest.json`),`utf-8`)),ve=JSON.parse(await a.default.readFile((0,i.join)(X,...U,`manifest.json`),`utf-8`)),Z=await a.default.readFile((0,i.join)(X,E),`utf-8`);a.default.rmSync((0,i.join)(X,E)),Z=se(Z,w);let Q=(await import(`p-queue`)).default||await import(`p-queue`),ye=new Q({concurrency:I}),be=new Q({concurrency:1}),xe={},Se=0;for(let e of J)ye.add(async()=>{try{let n=await pe(!1,e),{base:r,routes:c,triggerOnSSRAppRendered:l,transformState:d=t.n,app:f,routerType:h}=n,g=await A?.(e,Z,n)||Z,y=`${t.c(r)}${t.a(e)}`,S=ee(n),C=!f&&h===`remix`?await p({routes:[...c],locationArg:y,base:r,serverManifest:de,manifest:ve,ssrManifest:_e}):new Set,{appHTML:w,bodyAttributes:T,htmlAttributes:E,metaAttributes:D,styleTag:k,routerContext:M}=await S.render(e),P=M?.loaderData;if(P&&Object.keys(P).length>0){let n=ae(e,m);await a.default.ensureDir((0,i.join)(X,(0,i.dirname)(n))),await a.default.writeFile((0,i.join)(X,n),JSON.stringify(P)),xe[t.s(e)]=n,Se++}await l?.(e,w,n);let F=new o.JSDOM(await v({rootContainerId:L,appHTML:w,indexHTML:g,metaAttributes:D,bodyAttributes:T,htmlAttributes:E,initialState:null}));x(F.window.document,C);let I=F.serialize(),R=await j?.(e,I,n)||I;R=R.replace(_,`window.__VITE_REACT_SSG_HASH__ = '${m}'`),Y&&(R=await be.add(()=>Y.process(R)),R=R.replace(/<link\srel="stylesheet"/g,`<link rel="stylesheet" crossorigin`)),k&&(R=R.replace(`<head>`,`<head>${k}`));let z=await ce(R,O),B=`${(e.endsWith(`/`)?`${e}index`:e).replace(/^\//g,``)}.html`,V=N===`nested`?(0,i.join)(e.replace(/^\//g,``),`index.html`):B;await a.default.ensureDir((0,i.join)(X,(0,i.dirname)(V))),await a.default.writeFile((0,i.join)(X,V),z,`utf-8`),u.logger.info(`${(0,s.dim)(`${b}/`)}${(0,s.cyan)(V.padEnd(15,` `))} ${(0,s.dim)(te(z))}`)}catch(t){throw Error(`${(0,s.gray)(`[vite-react-ssg]`)} ${(0,s.red)(`Error on page: ${(0,s.cyan)(e)}`)}\n${t.stack}`)}});await ye.start().onIdle(),B(`Generating static loader data...`,Se);let Ce=JSON.stringify(xe,null,0);await a.default.writeFile((0,i.join)(X,`static-loader-data-manifest-${m}.json`),Ce),u.logger.info(`${(0,s.dim)(`${b}/`)}${(0,s.cyan)(`static-loader-data-manifest-${m}.json`.padEnd(15,` `))} ${(0,s.dim)(te(Ce))}`),await a.default.remove((0,i.join)(f,`.vite-react-ssg-temp`)),H();let $=u.plugins.find(e=>e.name===`vite-plugin-pwa`)?.api;$&&!$.disabled&&$.generateSW&&(B(`Regenerate PWA...`),await $.generateSW()),console.log(`\n${(0,s.gray)(`[vite-react-ssg]`)} ${(0,s.green)(`Build finished.`)}`),await M?.(b),setTimeout(()=>{console.log(`${(0,s.gray)(`[vite-react-ssg]`)} ${(0,s.yellow)(`Build process still running after 15s`)}. There might be something misconfigured in your setup. Force exit.`),process.exit(0)},15*1e3).unref()}function se(e,t){return!t||t===`sync`?e:e.replace(/<script type="module" /g,`<script type="module" ${t} `)}async function ce(e,t){if(t===`prettify`)try{let t=(await import(`prettier/esm/standalone.mjs`)).default,n=(await import(`prettier/esm/parser-html.mjs`)).default;return t.format(e,{semi:!1,parser:`html`,plugins:[n]})}catch(t){return console.error(`${(0,s.gray)(`[vite-react-ssg]`)} ${(0,s.red)(`Error formatting html: ${t?.message}`)}`),e}return e}function le({template:e,ssrEntry:n,onBeforePageRender:r,entry:i,rootContainerId:a,onPageRendered:o}){return{name:`vite-react-ssg:dev-server`,configureServer(s){let l=async(l,u,d)=>{try{let d=l.originalUrl,f=await(await s.ssrLoadModule(n).then(e=>e.createRoot))(!1,d),p=ee(f),{app:m,base:h}=f,[g,_]=d.split(`?`),y=new URLSearchParams(_);if(!m&&y.has(`_data`))return p.handleLoader(l,u);let x=await s.transformIndexHtml(d,e),S=await r?.(d,x,f)||x,{appHTML:C,bodyAttributes:w,htmlAttributes:T,metaAttributes:E,styleTag:D}=await p.render(t.o(g,h));E.push(D);let O=await Promise.all([n,i].map(async e=>await s.moduleGraph.getModuleByUrl(e))),k=new Set,A=new Set,j=async e=>{if(!e||!e?.ssrTransformResult||A.has(e))return;A.add(e);let{deps:t=[],dynamicDeps:n=[]}=e?.ssrTransformResult,r=[...t,...n];for(let e of r)if(e.endsWith(`.css`)||e.endsWith(`.scss`)||e.endsWith(`.sass`)||e.endsWith(`.less`))k.add(e);else if(e.endsWith(`.ts`)||e.endsWith(`.tsx`)){let t=await s.moduleGraph.getModuleByUrl(e);t&&await j(t)}};await Promise.all(O.map(async e=>j(e)));let M=[...k].map(e=>b(t.i(s.config.base,e)));E.push(...M);let N=await v({rootContainerId:a,appHTML:C,indexHTML:S,metaAttributes:E,bodyAttributes:w,htmlAttributes:T,initialState:null}),P=await o?.(d,N,f)||N;u.statusCode=200,u.setHeader(`Content-Type`,`text/html`),(0,c.send)(l,u,P,`html`,{headers:`pluginContainer`in s?s.config.server.headers:s.config.preview.headers})}catch(e){s.ssrFixStacktrace(e),console.error(`[vite-react-ssg] error: ${e.stack}`),u.statusCode=500,u.end(e.stack)}};return()=>{s.middlewares.use(l)}}}}async function G(e={},t={}){let n=process.env.MODE||process.env.NODE_ENV||t.mode||`development`,r=await(0,c.resolveConfig)(e,`serve`,n,n),o=process.cwd(),s=r.root||o,{htmlEntry:l=`index.html`,entry:u=await y(s,l),onBeforePageRender:d,onPageRendered:f,rootContainerId:p=`root`,mock:m=!1}=Object.assign({},r.ssgOptions||{},t),h=await ne(r,u),g=await a.default.readFile((0,i.join)(s,l),`utf-8`);if(process.env.__DEV_MODE_SSR=`true`,m){let{jsdomGlobal:e}=await Promise.resolve().then(()=>require(`./jsdomGlobal-DIW81D0t.cjs`));e()}return await(0,c.createServer)((0,c.mergeConfig)({...e,plugins:[...e.plugins??[],le({template:g,ssrEntry:h,onBeforePageRender:d,onPageRendered:f,entry:u,rootContainerId:p})]},{}))}async function ue(e={},t={},n){globalThis.__ssr_start_time=performance.now();try{let r=await G(t,e);return await r.listen(),K(r,!!n),r.bindCLIShortcuts({print:!0}),r}catch(e){console.error(`${(0,s.red)(`failed to start server. error:`)}\n${e.stack}`),process.exit(1)}}async function K(e,t=!1){if(t)return e.printUrls();let n=e.config.logger.info,r=` -- SSR`;globalThis.__ssr_start_time&&(r+=` ready in ${(0,s.reset)((0,s.bold)(`${Math.round(performance.now()-globalThis.__ssr_start_time)}ms`))}`),n(`\n ${(0,s.bgLightCyan)(` VITE-REACT-SSG v${z} `)}`,{clear:!e.config.logger.hasWarned}),n(`${(0,s.cyan)(`\n VITE v${c.version}`)+(0,s.dim)(r)}\n`),n((0,s.green)(` dev server running at:`)),e.printUrls()}exports.build=W,exports.createServer=G,exports.dev=ue;
@@ -0,0 +1,11 @@
1
+ import { u as ViteReactSSGOptions } from "./types-DfHnCTVN.cjs";
2
+ import { InlineConfig, ViteDevServer } from "vite";
3
+
4
+ //#region src/node/build.d.ts
5
+ declare function build(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig): Promise<void>;
6
+ //#endregion
7
+ //#region src/node/dev.d.ts
8
+ declare function createServer(viteConfig?: InlineConfig, ssgOptions?: Partial<ViteReactSSGOptions>): Promise<ViteDevServer>;
9
+ declare function dev(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig, customOptions?: unknown): Promise<ViteDevServer>;
10
+ //#endregion
11
+ export { build, createServer, dev };
@@ -0,0 +1,11 @@
1
+ import { u as ViteReactSSGOptions } from "./types-D9xYNy8A.mjs";
2
+ import { InlineConfig, ViteDevServer } from "vite";
3
+
4
+ //#region src/node/build.d.ts
5
+ declare function build(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig): Promise<void>;
6
+ //#endregion
7
+ //#region src/node/dev.d.ts
8
+ declare function createServer(viteConfig?: InlineConfig, ssgOptions?: Partial<ViteReactSSGOptions>): Promise<ViteDevServer>;
9
+ declare function dev(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig, customOptions?: unknown): Promise<ViteDevServer>;
10
+ //#endregion
11
+ export { build, createServer, dev };
package/dist/node.mjs ADDED
@@ -0,0 +1 @@
1
+ import{a as e,c as t,i as n,n as r,o as i,r as a,s as o}from"./state-BLI6QppB.mjs";import{createRequire as s}from"node:module";import{Fragment as c,jsx as l}from"react/jsx-runtime";import{dirname as u,isAbsolute as d,join as f}from"node:path";import p from"fs-extra";import{JSDOM as m}from"jsdom";import{bgLightCyan as h,blue as g,bold as _,cyan as v,dim as y,gray as b,green as x,red as S,reset as C,yellow as w}from"kolorist";import{build as T,createLogger as E,createServer as D,mergeConfig as O,resolveConfig as k,send as ee,version as A}from"vite";import{once as j}from"node:events";import{Readable as M,Writable as N}from"node:stream";import*as P from"react-dom/server";var F=s(import.meta.url);const te=/import\("([^)]+)"\)/g;async function ne({routes:e,locationArg:t,base:n,serverManifest:r,manifest:i,ssrManifest:a}){let{matchRoutes:o}=await import(`react-router-dom`),s=o([...e],t,n),c=s?.map(e=>e.route.entry).filter(Boolean)??[],l=new Set;s?.forEach(e=>{let t=``;e.route.lazy&&(t+=e.route.lazy.toString()),e.route.Component?._payload?._result&&(t+=e.route.Component._payload._result.toString());let n=t.matchAll(te);for(let e of n)l.add(e[1].split(`/`).at(-1)??``)});let u=new Set;c.forEach(e=>u.add(e));let d=[...Object.entries(r)];l.forEach(e=>{let t=d.find(([t,n])=>n.file.endsWith(e));t&&u.add(t[0])});let f=I(i,u),p=new Set;return Array.from(f).forEach(e=>{(a[e]||[]).forEach(e=>{p.add(e)})}),p}function I(e,t){let n=new Set;if(!t)return n;for(let r of t)L(e,r,n);return n}function L(e,t,n=new Set){return t?(n.add(t),e[t]?.dynamicImports?.forEach(t=>{L(e,t,n)}),n):n}async function re(e,t={}){try{let n=await import(`beasties`);return new(n.default||n)({path:e,logLevel:`warn`,external:!0,inlineFonts:!0,preloadFonts:!0,...t})}catch{}try{let n=await import(`critters`),r=n.default||n;return console.warn("`critters` is deprecated. Please use `beasties` instead."),new r({path:e,logLevel:`warn`,external:!0,inlineFonts:!0,preloadFonts:!0,...t})}catch{return}}const ie=`/* SCRIPT_COMMENT_PLACEHOLDER */`;async function ae({rootContainerId:e,indexHTML:t,appHTML:n,metaAttributes:r,bodyAttributes:i,htmlAttributes:a,initialState:o}){let s=o?`\n<script>window.__INITIAL_STATE__=${o}<\/script>`:``,c=`\n<script>${ie}<\/script>`,l=`<head>`,u=r.join(``);t=t.replace(l,l+u);let d=`<body`;t=t.replace(d,`${d} ${i}`);let f=`<html`;t=t.replace(f,`${f} ${a}`);let p=`<div id="${e}"></div>`;if(t.includes(p))return t.replace(p,`<div id="${e}" data-server-rendered="true">${n}</div>${s}${c}`);let m=await import(`html5parser`),h=m.parse(t),g;if(m.walk(h,{enter:r=>{if(!g&&r?.type===m.SyntaxKind.Tag&&Array.isArray(r.attributes)&&r.attributes.length>0&&r.attributes.some(t=>t.name.value===`id`&&t.value?.value===e)){let e=[...r.attributes.map(({name:{value:e},value:t})=>`${e}="${t.value}"`)].join(` `),i=t.slice(0,r.start),a=t.slice(r.end);g=`${i}<${r.name} ${e} data-server-rendered="true">${n}</${r.name}>${s}${c}${a}`}}}),!g)throw Error(`Could not find a tag with id="${e}" to replace it with server-side rendered HTML`);return g}async function oe(e,t=`index.html`){let[,n]=[...(await p.readFile(f(e,t),`utf-8`)).matchAll(/<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/gim)].find(e=>{let[t]=e,[,n]=t.match(/.*\stype=(?:'|")?([^>'"\s]+)/i)||[];return n===`module`})||[];return n||`src/main.ts`}function se(e){return`<link rel="stylesheet" href="${e}">`}function ce(e,t){let n=new Set;t&&t.forEach(t=>{n.has(t)||(n.add(t),le(e,t))})}function le(e,t){t.endsWith(`.js`)?R(e,{rel:`modulepreload`,crossOrigin:``,href:t}):t.endsWith(`.css`)?R(e,{rel:`stylesheet`,href:t,crossOrigin:``}):t.endsWith(`.woff`)||t.endsWith(`.woff2`)||t.endsWith(`.ttf`)?R(e,{rel:`preload`,as:`font`,type:`font/woff2`,href:t,crossOrigin:``}):(t.endsWith(`.png`)||t.endsWith(`.jpg`)||t.endsWith(`.jpeg`)||t.endsWith(`.webp`)||t.endsWith(`.gif`)||t.endsWith(`.ico`)||t.endsWith(`.svg`))&&R(e,{rel:`preload`,as:`image`,href:t,crossOrigin:``})}function ue(e){return e.createElement(`link`)}function de(e,t){let n=Object.keys(t);for(let r of n)e.setAttribute(r,t[r])}function R(e,t){if(e.head.querySelector(`link[href='${t.file}']`))return;let n=ue(e);de(n,t),e.head.appendChild(n)}function fe(e,t){if(e===!1||e==null)throw console.error(`The following error is a bug in Vite-react-ssg; please open an issue! https://github.com/Daydreamer-riri/vite-react-ssg/issues/new`),Error(t)}function pe(e){let t=new Headers;for(let[n,r]of Object.entries(e))if(r)if(Array.isArray(r))for(let e of r)t.append(n,e);else t.set(n,r);return t}function z(e){let t=e.headers.origin&&e.headers.origin!==`null`?e.headers.origin:`http://${e.headers.host}`;fe(e.originalUrl,"Expected `nodeReq.originalUrl` to be defined");let n=new URL(e.originalUrl,t),r={method:e.method,headers:pe(e.headers)};return new Request(n.href,r)}async function B(e,t){t.statusCode=e.status,t.statusMessage=e.statusText;for(let[n,r]of e.headers)t.setHeader(n,r);if(e.body){let n=e.body,r=M.from(n);r.pipe(t),await j(r,`end`)}else t.end()}function me(e){let t=new URL(e.url);t.searchParams.delete(`_data`);let n={method:e.method,body:e.body,headers:e.headers,signal:e.signal};return n.body&&(n.duplex=`half`),new Request(t.href,n)}async function V(e){if(!P.renderToPipeableStream)return P.renderToString(l(c,{children:e}));let t=new H,{pipe:n}=P.renderToPipeableStream(e,{onError(e){t.destroy(e)},onAllReady(){n(t)}});return t.getPromise()}var H=class extends N{constructor(){super(),this._output=``,this._deferred={promise:null,resolve:()=>null,reject:()=>null},this._deferred.promise=new Promise((e,t)=>{this._deferred.resolve=e,this._deferred.reject=t})}_write(e,t,n){this._output+=e.toString(),n()}_destroy(e,t){e instanceof Error?this._deferred.reject(e):t()}end(){return this._deferred.resolve(this._output),this.destroy()}getPromise(){return this._deferred.promise}};function he(e,t,n){let{helmet:r}=t,i=r.htmlAttributes.toString(),a=r.bodyAttributes.toString(),o=r.title.toString();o.split(`>`)[1]===`</title`&&(o=``);let s=[o,r.meta.toString(),r.link.toString(),r.script.toString()],c=n?.toString?.(e)??``;return{htmlAttributes:i,bodyAttributes:a,metaAttributes:s.filter(Boolean),styleTag:c}}const{HelmetProvider:U}=s(import.meta.url)(`react-helmet-async`);var ge=class{constructor(e){this.handleLoader=async(e,t)=>{let{routes:n,base:r}=this.context,{matchRoutes:i}=await import(`react-router-dom`),o=z(e),s=new URL(o.url),c=decodeURIComponent(s.searchParams.get(`_data`)),l=i(a([...n],e=>e),{pathname:s.pathname,search:s.search,hash:s.hash,state:null,key:`default`},r);if(!l){t.statusCode=404,t.end(`Route not found: ${c}`);return}let u=l.find(e=>e.route.id===c);if(!u){t.statusCode=404,t.end(`Route not found: ${c}`);return}let d=u.route.loader??await u.route.lazy?.().then(e=>e.loader);if(!d){t.statusCode=200,t.end(`There is no loader for the route: ${c}`);return}await B(await W({loader:d,params:u.params,request:o,routeId:c}),t)},this.context=e}async render(e){let{base:t,routes:n,getStyleCollector:r,routerOptions:i}=this.context,s=`http://localhost${o(e)}`,c=new Request(s),u=r?await r():null,d={},f=null,{StaticRouterProvider:p,createStaticHandler:m,createStaticRouter:h}=await import(`react-router-dom`),g=a([...n],e=>e),{query:_}=m(g),v=await _(c);if(v instanceof Response)throw v;f=v;let y=l(U,{context:d,children:l(p,{router:h(g,f,{future:i.future}),context:f})});u&&(y=u.collect(y));let b=await V(y),{htmlAttributes:x,bodyAttributes:S,metaAttributes:C,styleTag:w}=he(b,d,u);return{appHTML:b,htmlAttributes:x,bodyAttributes:S,metaAttributes:C,styleTag:w,routerContext:f}}};async function W({loader:e,params:t,request:n,routeId:r}){let{json:i}=await import(`react-router-dom`),a=await e({request:me(ve(n)),params:t});if(a===void 0)throw Error(`You defined a loader for route "${r}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`);return _e(a)?a:i(a)}function _e(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.headers==`object`&&e.body!==void 0}function ve(e){let t=new URL(e.url),n=t.searchParams.getAll(`index`);t.searchParams.delete(`index`);let r=[];for(let e of n)e&&r.push(e);for(let e of r)t.searchParams.append(`index`,e);let i={method:e.method,body:e.body,headers:e.headers,signal:e.signal};return i.body&&(i.duplex=`half`),new Request(t.href,i)}function ye(e){return new ge(e)}var G=`0.0.1`;function K(e,t){console.log(`\n${b(`[vite-react-ssg]`)} ${w(e)}${t?g(` (${t})`):``}`)}function be(e){return`${(e.length/1024).toFixed(2)} KiB`}async function xe(e){if(!e||e.length===0)return{paths:[`/`]};let t=new Set,n=async(e,i=``)=>{i=i.replace(/\/$/g,``);for(let a of e){if(a.lazy){let e=await a.lazy();e&&(a={...a,...e})}let e=a.path;if(e=r(e,i),a.getStaticPaths&&we(e)){let e=await a.getStaticPaths();for(let t of e)t=r(t,i),Array.isArray(a.children)&&await n(a.children,t)}a.index&&!e&&t.add(`/`),Array.isArray(a.children)&&await n(a.children,e)}};return await n(e),{paths:Array.from(t)};function r(e,n){return e!=null&&(e=n&&!e.startsWith(`/`)?`${n}${e?`/${e}`:``}`:e,t.add(e)),e}}async function Se(e,t){return await e.createResolver()(t,e.root)||(t.startsWith(`virtual:`)||t.includes(`\0`)?t:f(e.root,t))}const Ce=/[:*?]/;function we(e){return e?Ce.test(e):!1}const q=Number.parseInt(A)>=5?[`.vite`]:[];function Te(e){return Number.parseInt(A)>=8?{rolldownOptions:e}:{rollupOptions:e}}function Ee(e,t){return`static-loader-data${o(e===`/`?`/index`:e.endsWith(`/`)?`${e}index`:e)}.${t}.json`}function De(e,t){return e.filter(e=>!e.includes(`:`)&&!e.includes(`*`))}async function J(n={},i={}){let a=process.env.MODE||process.env.NODE_ENV||n.mode||`production`,c=await k(i,`build`,a,a),l=process.cwd(),h=c.root||l,_=Math.random().toString(36).substring(2,12),C=f(h,`.vite-react-ssg-temp`,_),D=c.build.outDir||`dist`,ee=c.base,A=Object.assign({},c.ssgOptions||{},n),{script:j=`sync`,mock:M=!1,htmlEntry:N=`index.html`,entry:P=await oe(h,N),formatting:te=`none`,includedRoutes:I=De,onBeforePageRender:L,onPageRendered:se,onFinished:le,dirStyle:ue=`flat`,includeAllRoutes:de=!1,format:R=`esm`,concurrency:fe=20,rootContainerId:pe=`root`}=A,z=A.beastiesOptions??A.crittersOptions??{};p.existsSync(C)&&await p.remove(C);let B=E(),me=B.warn;B.warn=(e,t)=>{e.includes(`vite:resolve`)&&e.includes(`externalized for browser compatibility`)||me(e,t)},K(`Build for client...`),await T(O(i,{build:{manifest:!0,ssrManifest:!0,...Te({input:{app:f(h,N||`./index.html`)},onLog(e,t,n){t.message.includes(`react-helmet-async`)||n(e,t)}})},customLogger:B,mode:c.mode,plugins:[{name:`vite-react-ssg:get-oup-dir`,configResolved(e){D=e.build.outDir||`dist`}}]}));let V=()=>{};if(M){let{jsdomGlobal:e}=await import(`./jsdomGlobal-DuvGNWb6.mjs`);V=e()}K(`Build for server...`),process.env.VITE_SSG=`true`;let H=await Se(c,P);await T(O(i,{build:{ssr:H,manifest:!0,outDir:C,minify:!1,cssCodeSplit:!1,...Te({output:R===`esm`?{entryFileNames:`[name].mjs`,format:`esm`}:{entryFileNames:`[name].cjs`,format:`cjs`},onLog(e,t,n){t.message.includes(`react-helmet-async`)||n(e,t)}})},mode:c.mode}));let he=R===`esm`&&process.platform===`win32`?`file://`:``,U=R===`esm`?`.mjs`:`.cjs`,ge=H.replace(/\0/g,``).replace(`virtual:`,``).replace(/[^a-zA-Z0-9-]/g,`_`),W=he+f(C,(H.includes(`/`)||H.includes(`\\`)?H.split(/[/\\]/).pop().replace(U,``):ge)+U).replace(/\\/g,`/`),_e=JSON.parse(await p.readFile(f(C,...q,`manifest.json`),`utf-8`)),ve=F===void 0?s(import.meta.url):F,{createRoot:G,includedRoutes:Ce}=R===`esm`?await import(W):ve(W),we=Ce||I,{routes:J}=await G(!1),{paths:Ae}=await xe(J),Y=de?Ae:await we(Ae,J||[]);Y=De(Y,J||[]),Y=Array.from(new Set(Y)),K(`Rendering Pages...`,Y.length);let X=z===!1?void 0:await re(D,{publicPath:ee,...z});X&&console.log(`${b(`[vite-react-ssg]`)} ${g("Critical CSS generation enabled via `beasties`")}`);let Z=d(D)?D:f(h,D),je=JSON.parse(await p.readFile(f(Z,...q,`ssr-manifest.json`),`utf-8`)),Me=JSON.parse(await p.readFile(f(Z,...q,`manifest.json`),`utf-8`)),Q=await p.readFile(f(Z,N),`utf-8`);p.rmSync(f(Z,N)),Q=Oe(Q,j);let Ne=(await import(`p-queue`)).default||await import(`p-queue`),Pe=new Ne({concurrency:fe}),Fe=new Ne({concurrency:1}),Ie={},Le=0;for(let n of Y)Pe.add(async()=>{try{let i=await G(!1,n),{base:a,routes:s,triggerOnSSRAppRendered:l,transformState:d=r,app:h,routerType:g}=i,b=await L?.(n,Q,i)||Q,x=`${t(a)}${e(n)}`,S=ye(i),C=!h&&g===`remix`?await ne({routes:[...s],locationArg:x,base:a,serverManifest:_e,manifest:Me,ssrManifest:je}):new Set,{appHTML:w,bodyAttributes:T,htmlAttributes:E,metaAttributes:O,styleTag:k,routerContext:ee}=await S.render(n),A=ee?.loaderData;if(A&&Object.keys(A).length>0){let e=Ee(n,_);await p.ensureDir(f(Z,u(e))),await p.writeFile(f(Z,e),JSON.stringify(A)),Ie[o(n)]=e,Le++}await l?.(n,w,i);let j=new m(await ae({rootContainerId:pe,appHTML:w,indexHTML:b,metaAttributes:O,bodyAttributes:T,htmlAttributes:E,initialState:null}));ce(j.window.document,C);let M=j.serialize(),N=await se?.(n,M,i)||M;N=N.replace(ie,`window.__VITE_REACT_SSG_HASH__ = '${_}'`),X&&(N=await Fe.add(()=>X.process(N)),N=N.replace(/<link\srel="stylesheet"/g,`<link rel="stylesheet" crossorigin`)),k&&(N=N.replace(`<head>`,`<head>${k}`));let P=await ke(N,te),F=`${(n.endsWith(`/`)?`${n}index`:n).replace(/^\//g,``)}.html`,I=ue===`nested`?f(n.replace(/^\//g,``),`index.html`):F;await p.ensureDir(f(Z,u(I))),await p.writeFile(f(Z,I),P,`utf-8`),c.logger.info(`${y(`${D}/`)}${v(I.padEnd(15,` `))} ${y(be(P))}`)}catch(e){throw Error(`${b(`[vite-react-ssg]`)} ${S(`Error on page: ${v(n)}`)}\n${e.stack}`)}});await Pe.start().onIdle(),K(`Generating static loader data...`,Le);let Re=JSON.stringify(Ie,null,0);await p.writeFile(f(Z,`static-loader-data-manifest-${_}.json`),Re),c.logger.info(`${y(`${D}/`)}${v(`static-loader-data-manifest-${_}.json`.padEnd(15,` `))} ${y(be(Re))}`),await p.remove(f(h,`.vite-react-ssg-temp`)),V();let $=c.plugins.find(e=>e.name===`vite-plugin-pwa`)?.api;$&&!$.disabled&&$.generateSW&&(K(`Regenerate PWA...`),await $.generateSW()),console.log(`\n${b(`[vite-react-ssg]`)} ${x(`Build finished.`)}`),await le?.(D),setTimeout(()=>{console.log(`${b(`[vite-react-ssg]`)} ${w(`Build process still running after 15s`)}. There might be something misconfigured in your setup. Force exit.`),process.exit(0)},15*1e3).unref()}function Oe(e,t){return!t||t===`sync`?e:e.replace(/<script type="module" /g,`<script type="module" ${t} `)}async function ke(e,t){if(t===`prettify`)try{let t=(await import(`prettier/esm/standalone.mjs`)).default,n=(await import(`prettier/esm/parser-html.mjs`)).default;return t.format(e,{semi:!1,parser:`html`,plugins:[n]})}catch(t){return console.error(`${b(`[vite-react-ssg]`)} ${S(`Error formatting html: ${t?.message}`)}`),e}return e}function Ae({template:e,ssrEntry:t,onBeforePageRender:r,entry:a,rootContainerId:o,onPageRendered:s}){return{name:`vite-react-ssg:dev-server`,configureServer(c){let l=async(l,u,d)=>{try{let d=l.originalUrl,f=await(await c.ssrLoadModule(t).then(e=>e.createRoot))(!1,d),p=ye(f),{app:m,base:h}=f,[g,_]=d.split(`?`),v=new URLSearchParams(_);if(!m&&v.has(`_data`))return p.handleLoader(l,u);let y=await c.transformIndexHtml(d,e),b=await r?.(d,y,f)||y,{appHTML:x,bodyAttributes:S,htmlAttributes:C,metaAttributes:w,styleTag:T}=await p.render(i(g,h));w.push(T);let E=await Promise.all([t,a].map(async e=>await c.moduleGraph.getModuleByUrl(e))),D=new Set,O=new Set,k=async e=>{if(!e||!e?.ssrTransformResult||O.has(e))return;O.add(e);let{deps:t=[],dynamicDeps:n=[]}=e?.ssrTransformResult,r=[...t,...n];for(let e of r)if(e.endsWith(`.css`)||e.endsWith(`.scss`)||e.endsWith(`.sass`)||e.endsWith(`.less`))D.add(e);else if(e.endsWith(`.ts`)||e.endsWith(`.tsx`)){let t=await c.moduleGraph.getModuleByUrl(e);t&&await k(t)}};await Promise.all(E.map(async e=>k(e)));let A=[...D].map(e=>se(n(c.config.base,e)));w.push(...A);let j=await ae({rootContainerId:o,appHTML:x,indexHTML:b,metaAttributes:w,bodyAttributes:S,htmlAttributes:C,initialState:null}),M=await s?.(d,j,f)||j;u.statusCode=200,u.setHeader(`Content-Type`,`text/html`),ee(l,u,M,`html`,{headers:`pluginContainer`in c?c.config.server.headers:c.config.preview.headers})}catch(e){c.ssrFixStacktrace(e),console.error(`[vite-react-ssg] error: ${e.stack}`),u.statusCode=500,u.end(e.stack)}};return()=>{c.middlewares.use(l)}}}}async function Y(e={},t={}){let n=process.env.MODE||process.env.NODE_ENV||t.mode||`development`,r=await k(e,`serve`,n,n),i=process.cwd(),a=r.root||i,{htmlEntry:o=`index.html`,entry:s=await oe(a,o),onBeforePageRender:c,onPageRendered:l,rootContainerId:u=`root`,mock:d=!1}=Object.assign({},r.ssgOptions||{},t),m=await Se(r,s),h=await p.readFile(f(a,o),`utf-8`);if(process.env.__DEV_MODE_SSR=`true`,d){let{jsdomGlobal:e}=await import(`./jsdomGlobal-DuvGNWb6.mjs`);e()}return await D(O({...e,plugins:[...e.plugins??[],Ae({template:h,ssrEntry:m,onBeforePageRender:c,onPageRendered:l,entry:s,rootContainerId:u})]},{}))}async function X(e={},t={},n){globalThis.__ssr_start_time=performance.now();try{let r=await Y(t,e);return await r.listen(),Z(r,!!n),r.bindCLIShortcuts({print:!0}),r}catch(e){console.error(`${S(`failed to start server. error:`)}\n${e.stack}`),process.exit(1)}}async function Z(e,t=!1){if(t)return e.printUrls();let n=e.config.logger.info,r=` -- SSR`;globalThis.__ssr_start_time&&(r+=` ready in ${C(_(`${Math.round(performance.now()-globalThis.__ssr_start_time)}ms`))}`),n(`\n ${h(` VITE-REACT-SSG v${G} `)}`,{clear:!e.config.logger.hasWarned}),n(`${v(`\n VITE v${A}`)+y(r)}\n`),n(x(` dev server running at:`)),e.printUrls()}export{J as build,Y as createServer,X as dev};
@@ -0,0 +1 @@
1
+ function e(e,t){return!e||!t?e||t||``:(e[e.length-1]===`/`&&(e=e.substring(0,e.length-1)),t[0]!==`/`&&(t=`/${t}`),e+t)}function t(e){return e[0]===`/`?e.slice(1):e}function n(e,t){if(e===t)return`/`;let n=r(t);return e.startsWith(n)?e.slice(n.length-1):e}function r(e){return e[e.length-1]===`/`?e:`${e}/`}function i(e){return e[0]===`/`?e:`/${e}`}function a(e,t,n=[]){return e.map((e,r)=>{let i=[...n,String(r)],s=typeof e.id==`string`?e.id:i.join(`-`);if(e.id=s,o(e))return{...e,...t(e),id:s};{let n={...e,...t(e),id:s,children:void 0};return e.children&&(n.children=a(e.children,t,i)),n}})}function o(e){return e.index===!0}const s=/[<>/\u2028\u2029]/g,c={"<":`\\u003C`,">":`\\u003E`,"/":`\\u002F`,"\u2028":`\\u2028`,"\u2029":`\\u2029`};function l(e){return c[e]}function u(e){if(e==null||Object.keys(e).length===0)return null;try{return JSON.stringify(JSON.stringify(e||{})).replace(s,l)}catch(t){return console.error(`[SSG] On state serialization -`,t,e),null}}function d(e){try{return JSON.parse(e||`{}`)}catch(t){return console.error(`[SSG] On state deserialization -`,t,e),{}}}export{t as a,r as c,e as i,u as n,n as o,a as r,i as s,d as t};
@@ -0,0 +1 @@
1
+ function e(e,t){return!e||!t?e||t||``:(e[e.length-1]===`/`&&(e=e.substring(0,e.length-1)),t[0]!==`/`&&(t=`/${t}`),e+t)}function t(e){return e[0]===`/`?e.slice(1):e}function n(e,t){if(e===t)return`/`;let n=r(t);return e.startsWith(n)?e.slice(n.length-1):e}function r(e){return e[e.length-1]===`/`?e:`${e}/`}function i(e){return e[0]===`/`?e:`/${e}`}function a(e,t,n=[]){return e.map((e,r)=>{let i=[...n,String(r)],s=typeof e.id==`string`?e.id:i.join(`-`);if(e.id=s,o(e))return{...e,...t(e),id:s};{let n={...e,...t(e),id:s,children:void 0};return e.children&&(n.children=a(e.children,t,i)),n}})}function o(e){return e.index===!0}const s=/[<>/\u2028\u2029]/g,c={"<":`\\u003C`,">":`\\u003E`,"/":`\\u002F`,"\u2028":`\\u2028`,"\u2029":`\\u2029`};function l(e){return c[e]}function u(e){if(e==null||Object.keys(e).length===0)return null;try{return JSON.stringify(JSON.stringify(e||{})).replace(s,l)}catch(t){return console.error(`[SSG] On state serialization -`,t,e),null}}function d(e){try{return JSON.parse(e||`{}`)}catch(t){return console.error(`[SSG] On state deserialization -`,t,e),{}}}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return d}});
@@ -0,0 +1 @@
1
+ let e=require(`styled-components`);async function t(){let t=new e.ServerStyleSheet;return{collect(e){return t.collectStyles(e)},toString(){return t.getStyleTags()},cleanup(){t.seal()}}}module.exports=t;
@@ -0,0 +1,9 @@
1
+ import { ReactElement } from "react";
2
+
3
+ //#region src/style-collectors/styled-components.d.ts
4
+ declare function ssrCollector(): Promise<{
5
+ collect(app: ReactElement): JSX.Element;
6
+ toString(): string;
7
+ cleanup(): void;
8
+ }>;
9
+ export = ssrCollector;
@@ -0,0 +1,10 @@
1
+ import { ReactElement } from "react";
2
+
3
+ //#region src/style-collectors/styled-components.d.ts
4
+ declare function ssrCollector(): Promise<{
5
+ collect(app: ReactElement): JSX.Element;
6
+ toString(): string;
7
+ cleanup(): void;
8
+ }>;
9
+ //#endregion
10
+ export { ssrCollector as default };
@@ -0,0 +1 @@
1
+ import{ServerStyleSheet as e}from"styled-components";async function t(){let t=new e;return{collect(e){return t.collectStyles(e)},toString(){return t.getStyleTags()},cleanup(){t.seal()}}}export{t as default};
@@ -0,0 +1,221 @@
1
+ import { FutureConfig, IndexRouteObject, NonIndexRouteObject, createBrowserRouter } from "react-router-dom";
2
+ import { ReactElement, ReactNode } from "react";
3
+ import { Options } from "beasties";
4
+
5
+ //#region src/types.d.ts
6
+ type Router = ReturnType<typeof createBrowserRouter>;
7
+ interface CrittersOptions {
8
+ path?: string;
9
+ publicPath?: string;
10
+ external?: boolean;
11
+ inlineThreshold?: number;
12
+ minimumExternalSize?: number;
13
+ pruneSource?: boolean;
14
+ mergeStylesheets?: boolean;
15
+ additionalStylesheets?: string[];
16
+ preload?: 'body' | 'media' | 'swap' | 'js' | 'js-lazy';
17
+ noscriptFallback?: boolean;
18
+ inlineFonts?: boolean;
19
+ preloadFonts?: boolean;
20
+ fonts?: boolean;
21
+ keyframes?: string;
22
+ compress?: boolean;
23
+ logLevel?: 'info' | 'warn' | 'error' | 'trace' | 'debug' | 'silent';
24
+ reduceInlineStyles?: boolean;
25
+ }
26
+ interface ViteReactSSGOptions<Context = ViteReactSSGContext> {
27
+ /**
28
+ * Set the scripts' loading mode. Only works for `type="module"`.
29
+ *
30
+ * @default 'sync'
31
+ */
32
+ script?: 'sync' | 'async' | 'defer' | 'async defer';
33
+ /**
34
+ * Build format.
35
+ *
36
+ * @default 'esm'
37
+ */
38
+ format?: 'esm' | 'cjs';
39
+ /**
40
+ * The path of the main entry file (relative to the project root).
41
+ *
42
+ * @default 'src/main.ts'
43
+ */
44
+ entry?: string;
45
+ /**
46
+ * The path of the index.html file (relative to the project root).
47
+ * @default 'index.html'
48
+ */
49
+ htmlEntry?: string;
50
+ /**
51
+ * Mock browser global variables (window, document, etc...) from SSG.
52
+ *
53
+ * @default false
54
+ */
55
+ mock?: boolean;
56
+ /**
57
+ * Apply formatter to the generated index file.
58
+ *
59
+ * **It will cause Hydration Failed.**
60
+ *
61
+ * @default 'none'
62
+ */
63
+ formatting?: 'prettify' | 'none';
64
+ /**
65
+ * Vite environmeng mode.
66
+ */
67
+ mode?: string;
68
+ /**
69
+ * Directory style of the output directory.
70
+ *
71
+ * flat: `/foo` -> `/foo.html`
72
+ * nested: `/foo` -> `/foo/index.html`
73
+ *
74
+ * @default 'flat'
75
+ */
76
+ dirStyle?: 'flat' | 'nested';
77
+ /**
78
+ * Generate for all routes, including dynamic routes.
79
+ * If enabled, you will need to configGure your serve
80
+ * manually to handle dynamic routes properly.
81
+ *
82
+ * @default false
83
+ */
84
+ includeAllRoutes?: boolean;
85
+ /**
86
+ * Options for the critters packages.
87
+ *
88
+ * @deprecated Use `beastiesOptions` instead.
89
+ * @see https://github.com/GoogleChromeLabs/critters
90
+ */
91
+ crittersOptions?: CrittersOptions | false;
92
+ /**
93
+ * Options for the beasties package.
94
+ *
95
+ * @see https://github.com/danielroe/beasties
96
+ */
97
+ beastiesOptions?: Options | false;
98
+ /**
99
+ * Custom function to modify the routes to do the SSG.
100
+ *
101
+ * Works only when `includeAllRoutes` is set to false.
102
+ *
103
+ * Defaults to a handler that filters out all the dynamic routes.
104
+ * When passing your custom handler, you should also take care of the dynamic routes yourself.
105
+ */
106
+ includedRoutes?: (paths: string[], routes: Readonly<RouteRecord[]>) => Promise<string[]> | string[];
107
+ /**
108
+ * Callback to be called before every page render.
109
+ *
110
+ * It can be used to transform the project's `index.html` file before passing it to the renderer.
111
+ *
112
+ * To do so, you can change the 'index.html' file contents (passed in through the `indexHTML` parameter), and return it.
113
+ * The returned value will then be passed to renderer.
114
+ */
115
+ onBeforePageRender?: (route: string, indexHTML: string, appCtx: Context) => Promise<string | null | undefined> | string | null | undefined;
116
+ /**
117
+ * Callback to be called on every rendered page.
118
+ *
119
+ * It can be used to transform the current route's rendered HTML.
120
+ *
121
+ * To do so, you can transform the route's rendered HTML (passed in through the `renderedHTML` parameter), and return it.
122
+ * The returned value will be used as the HTML of the route.
123
+ */
124
+ onPageRendered?: (route: string, renderedHTML: string, appCtx: Context) => Promise<string | null | undefined> | string | null | undefined;
125
+ onFinished?: (dir: string) => Promise<void> | void;
126
+ /**
127
+ * The application's root container `id`.
128
+ *
129
+ * @default `root`
130
+ */
131
+ rootContainerId?: string;
132
+ /**
133
+ * The size of the SSG processing queue.
134
+ *
135
+ * @default 20
136
+ */
137
+ concurrency?: number;
138
+ }
139
+ interface ViteReactSSGContext<HasRouter extends boolean = true> {
140
+ router?: HasRouter extends true ? Router : undefined;
141
+ routes: HasRouter extends true ? Readonly<RouteRecord[]> : undefined;
142
+ routerOptions: HasRouter extends true ? RouterOptions : undefined;
143
+ initialState: Record<string, any>;
144
+ isClient: boolean;
145
+ onSSRAppRendered: (cb: Function) => void;
146
+ triggerOnSSRAppRendered: (route: string, appHTML: string, appCtx: ViteReactSSGContext) => Promise<unknown[]>;
147
+ transformState?: (state: any) => any;
148
+ /**
149
+ * Current router path on SSG, `undefined` on client side.
150
+ */
151
+ routePath?: string;
152
+ base: string;
153
+ getStyleCollector: (() => StyleCollector | Promise<StyleCollector>) | null;
154
+ app?: HasRouter extends true ? never : ReactNode;
155
+ routerType: 'remix' | 'single-page';
156
+ }
157
+ interface ViteReactSSGClientOptions {
158
+ transformState?: (state: any) => any;
159
+ registerComponents?: boolean;
160
+ /**
161
+ * The application's root container query selector.
162
+ *
163
+ * @default `#root`
164
+ */
165
+ rootContainer?: string | Element;
166
+ /**
167
+ * @deprecated This option is no longer needed
168
+ */
169
+ ssrWhenDev?: boolean;
170
+ getStyleCollector?: (() => StyleCollector | Promise<StyleCollector>) | null;
171
+ useLegacyRender?: boolean;
172
+ }
173
+ interface CommonRouteOptions {
174
+ /**
175
+ * Used to obtain static resources through manifest
176
+ *
177
+ * **You are not required to use this field. It is only necessary when "prehydration style loss" occurs.**
178
+ *
179
+ * @example `src/pages/home.tsx`
180
+ */
181
+ entry?: string;
182
+ /**
183
+ * The getStaticPaths() function should return an array of path
184
+ * to determine which paths will be pre-rendered by vite-react-ssg.
185
+ *
186
+ * This function is only valid for dynamic route.
187
+ *
188
+ * @example () => ['path1', 'path2']
189
+ */
190
+ getStaticPaths?: () => string[] | Promise<string[]>;
191
+ }
192
+ type NonIndexRouteRecord = Omit<NonIndexRouteObject, 'children'> & {
193
+ children?: RouteRecord[];
194
+ } & CommonRouteOptions;
195
+ type IndexRouteRecord = IndexRouteObject & CommonRouteOptions;
196
+ type RouteRecord = NonIndexRouteRecord | IndexRouteRecord;
197
+ interface RouterFutureConfig {
198
+ v7_fetcherPersist?: boolean;
199
+ v7_normalizeFormMethod?: boolean;
200
+ v7_partialHydration?: boolean;
201
+ v7_relativeSplatPath?: boolean;
202
+ v7_skipActionErrorRevalidation?: boolean;
203
+ }
204
+ interface RouterOptions {
205
+ routes: RouteRecord[];
206
+ basename?: string;
207
+ future?: Partial<RouterFutureConfig & FutureConfig>;
208
+ customCreateRouter?: typeof createBrowserRouter;
209
+ }
210
+ interface StyleCollector {
211
+ collect: (app: ReactElement) => ReactElement;
212
+ toString: (html: string) => string;
213
+ cleanup?: () => void;
214
+ }
215
+ declare module 'vite' {
216
+ interface UserConfig {
217
+ ssgOptions?: ViteReactSSGOptions;
218
+ }
219
+ }
220
+ //#endregion
221
+ export { RouterFutureConfig as a, ViteReactSSGClientOptions as c, RouteRecord as i, ViteReactSSGContext as l, IndexRouteRecord as n, RouterOptions as o, NonIndexRouteRecord as r, StyleCollector as s, CrittersOptions as t, ViteReactSSGOptions as u };
@@ -0,0 +1,221 @@
1
+ import { Options } from "beasties";
2
+ import { ReactElement, ReactNode } from "react";
3
+ import { FutureConfig, IndexRouteObject, NonIndexRouteObject, createBrowserRouter } from "react-router-dom";
4
+
5
+ //#region src/types.d.ts
6
+ type Router = ReturnType<typeof createBrowserRouter>;
7
+ interface CrittersOptions {
8
+ path?: string;
9
+ publicPath?: string;
10
+ external?: boolean;
11
+ inlineThreshold?: number;
12
+ minimumExternalSize?: number;
13
+ pruneSource?: boolean;
14
+ mergeStylesheets?: boolean;
15
+ additionalStylesheets?: string[];
16
+ preload?: 'body' | 'media' | 'swap' | 'js' | 'js-lazy';
17
+ noscriptFallback?: boolean;
18
+ inlineFonts?: boolean;
19
+ preloadFonts?: boolean;
20
+ fonts?: boolean;
21
+ keyframes?: string;
22
+ compress?: boolean;
23
+ logLevel?: 'info' | 'warn' | 'error' | 'trace' | 'debug' | 'silent';
24
+ reduceInlineStyles?: boolean;
25
+ }
26
+ interface ViteReactSSGOptions<Context = ViteReactSSGContext> {
27
+ /**
28
+ * Set the scripts' loading mode. Only works for `type="module"`.
29
+ *
30
+ * @default 'sync'
31
+ */
32
+ script?: 'sync' | 'async' | 'defer' | 'async defer';
33
+ /**
34
+ * Build format.
35
+ *
36
+ * @default 'esm'
37
+ */
38
+ format?: 'esm' | 'cjs';
39
+ /**
40
+ * The path of the main entry file (relative to the project root).
41
+ *
42
+ * @default 'src/main.ts'
43
+ */
44
+ entry?: string;
45
+ /**
46
+ * The path of the index.html file (relative to the project root).
47
+ * @default 'index.html'
48
+ */
49
+ htmlEntry?: string;
50
+ /**
51
+ * Mock browser global variables (window, document, etc...) from SSG.
52
+ *
53
+ * @default false
54
+ */
55
+ mock?: boolean;
56
+ /**
57
+ * Apply formatter to the generated index file.
58
+ *
59
+ * **It will cause Hydration Failed.**
60
+ *
61
+ * @default 'none'
62
+ */
63
+ formatting?: 'prettify' | 'none';
64
+ /**
65
+ * Vite environmeng mode.
66
+ */
67
+ mode?: string;
68
+ /**
69
+ * Directory style of the output directory.
70
+ *
71
+ * flat: `/foo` -> `/foo.html`
72
+ * nested: `/foo` -> `/foo/index.html`
73
+ *
74
+ * @default 'flat'
75
+ */
76
+ dirStyle?: 'flat' | 'nested';
77
+ /**
78
+ * Generate for all routes, including dynamic routes.
79
+ * If enabled, you will need to configGure your serve
80
+ * manually to handle dynamic routes properly.
81
+ *
82
+ * @default false
83
+ */
84
+ includeAllRoutes?: boolean;
85
+ /**
86
+ * Options for the critters packages.
87
+ *
88
+ * @deprecated Use `beastiesOptions` instead.
89
+ * @see https://github.com/GoogleChromeLabs/critters
90
+ */
91
+ crittersOptions?: CrittersOptions | false;
92
+ /**
93
+ * Options for the beasties package.
94
+ *
95
+ * @see https://github.com/danielroe/beasties
96
+ */
97
+ beastiesOptions?: Options | false;
98
+ /**
99
+ * Custom function to modify the routes to do the SSG.
100
+ *
101
+ * Works only when `includeAllRoutes` is set to false.
102
+ *
103
+ * Defaults to a handler that filters out all the dynamic routes.
104
+ * When passing your custom handler, you should also take care of the dynamic routes yourself.
105
+ */
106
+ includedRoutes?: (paths: string[], routes: Readonly<RouteRecord[]>) => Promise<string[]> | string[];
107
+ /**
108
+ * Callback to be called before every page render.
109
+ *
110
+ * It can be used to transform the project's `index.html` file before passing it to the renderer.
111
+ *
112
+ * To do so, you can change the 'index.html' file contents (passed in through the `indexHTML` parameter), and return it.
113
+ * The returned value will then be passed to renderer.
114
+ */
115
+ onBeforePageRender?: (route: string, indexHTML: string, appCtx: Context) => Promise<string | null | undefined> | string | null | undefined;
116
+ /**
117
+ * Callback to be called on every rendered page.
118
+ *
119
+ * It can be used to transform the current route's rendered HTML.
120
+ *
121
+ * To do so, you can transform the route's rendered HTML (passed in through the `renderedHTML` parameter), and return it.
122
+ * The returned value will be used as the HTML of the route.
123
+ */
124
+ onPageRendered?: (route: string, renderedHTML: string, appCtx: Context) => Promise<string | null | undefined> | string | null | undefined;
125
+ onFinished?: (dir: string) => Promise<void> | void;
126
+ /**
127
+ * The application's root container `id`.
128
+ *
129
+ * @default `root`
130
+ */
131
+ rootContainerId?: string;
132
+ /**
133
+ * The size of the SSG processing queue.
134
+ *
135
+ * @default 20
136
+ */
137
+ concurrency?: number;
138
+ }
139
+ interface ViteReactSSGContext<HasRouter extends boolean = true> {
140
+ router?: HasRouter extends true ? Router : undefined;
141
+ routes: HasRouter extends true ? Readonly<RouteRecord[]> : undefined;
142
+ routerOptions: HasRouter extends true ? RouterOptions : undefined;
143
+ initialState: Record<string, any>;
144
+ isClient: boolean;
145
+ onSSRAppRendered: (cb: Function) => void;
146
+ triggerOnSSRAppRendered: (route: string, appHTML: string, appCtx: ViteReactSSGContext) => Promise<unknown[]>;
147
+ transformState?: (state: any) => any;
148
+ /**
149
+ * Current router path on SSG, `undefined` on client side.
150
+ */
151
+ routePath?: string;
152
+ base: string;
153
+ getStyleCollector: (() => StyleCollector | Promise<StyleCollector>) | null;
154
+ app?: HasRouter extends true ? never : ReactNode;
155
+ routerType: 'remix' | 'single-page';
156
+ }
157
+ interface ViteReactSSGClientOptions {
158
+ transformState?: (state: any) => any;
159
+ registerComponents?: boolean;
160
+ /**
161
+ * The application's root container query selector.
162
+ *
163
+ * @default `#root`
164
+ */
165
+ rootContainer?: string | Element;
166
+ /**
167
+ * @deprecated This option is no longer needed
168
+ */
169
+ ssrWhenDev?: boolean;
170
+ getStyleCollector?: (() => StyleCollector | Promise<StyleCollector>) | null;
171
+ useLegacyRender?: boolean;
172
+ }
173
+ interface CommonRouteOptions {
174
+ /**
175
+ * Used to obtain static resources through manifest
176
+ *
177
+ * **You are not required to use this field. It is only necessary when "prehydration style loss" occurs.**
178
+ *
179
+ * @example `src/pages/home.tsx`
180
+ */
181
+ entry?: string;
182
+ /**
183
+ * The getStaticPaths() function should return an array of path
184
+ * to determine which paths will be pre-rendered by vite-react-ssg.
185
+ *
186
+ * This function is only valid for dynamic route.
187
+ *
188
+ * @example () => ['path1', 'path2']
189
+ */
190
+ getStaticPaths?: () => string[] | Promise<string[]>;
191
+ }
192
+ type NonIndexRouteRecord = Omit<NonIndexRouteObject, 'children'> & {
193
+ children?: RouteRecord[];
194
+ } & CommonRouteOptions;
195
+ type IndexRouteRecord = IndexRouteObject & CommonRouteOptions;
196
+ type RouteRecord = NonIndexRouteRecord | IndexRouteRecord;
197
+ interface RouterFutureConfig {
198
+ v7_fetcherPersist?: boolean;
199
+ v7_normalizeFormMethod?: boolean;
200
+ v7_partialHydration?: boolean;
201
+ v7_relativeSplatPath?: boolean;
202
+ v7_skipActionErrorRevalidation?: boolean;
203
+ }
204
+ interface RouterOptions {
205
+ routes: RouteRecord[];
206
+ basename?: string;
207
+ future?: Partial<RouterFutureConfig & FutureConfig>;
208
+ customCreateRouter?: typeof createBrowserRouter;
209
+ }
210
+ interface StyleCollector {
211
+ collect: (app: ReactElement) => ReactElement;
212
+ toString: (html: string) => string;
213
+ cleanup?: () => void;
214
+ }
215
+ declare module 'vite' {
216
+ interface UserConfig {
217
+ ssgOptions?: ViteReactSSGOptions;
218
+ }
219
+ }
220
+ //#endregion
221
+ export { RouterFutureConfig as a, ViteReactSSGClientOptions as c, RouteRecord as i, ViteReactSSGContext as l, IndexRouteRecord as n, RouterOptions as o, NonIndexRouteRecord as r, StyleCollector as s, CrittersOptions as t, ViteReactSSGOptions as u };