@lomray/vite-ssr-boost 1.0.0-beta.29 → 1.0.0-beta.30

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/cli/build.js CHANGED
@@ -1,2 +1,2 @@
1
- import o from"node:child_process";import{performance as e}from"node:perf_hooks";import t from"chalk";import i from"./vite-reset-cache.js";import s from"../constants/cli-name.js";import{createDevMarker as r}from"../helpers/dev-marker.js";import n from"../services/build.js";async function a({onFinish:a,isOnlyClient:l=!1,isWatch:d=!1,isUnlockRobots:c=!1,isEject:m=!1,clientOptions:p="",serverOptions:u="",mode:O=""}){const f=e.now(),v=new n({mode:O}),S=["client"],$=new AbortController,_=O?`--mode ${O}`:"";await v.makeConfig(),await i(),v.clearBuildFolder();const b=v.promisifyProcess(o.spawn(`vite build ${p} --emptyOutDir --outDir ${v.outDir}/client ${_}`,{signal:$.signal,stdio:[process.stdin,"pipe",process.stderr],shell:!0,env:{...process.env,FORCE_COLOR:"2",SSR_BOOST_IS_SSR:l?"0":"1",SSR_BOOST_ACTION:global.viteBoostAction}}));let g;if(d||await b,l||(g=v.promisifyProcess(o.spawn(`vite build ${u} --emptyOutDir --outDir ${v.outDir}/server --ssr ${v.serverFile} ${_}`,{signal:$.signal,stdio:[process.stdin,"pipe",process.stderr],shell:!0,env:{...process.env,FORCE_COLOR:"2",SSR_BOOST_IS_SSR:l?"0":"1",SSR_BOOST_ACTION:global.viteBoostAction}})),d||(await g,await v.buildManifest(),m&&v.eject()),S.push("server")),d){process.on("exit",(()=>{$.abort()}));let o=l?1:2;const e=t=>{Buffer.from(t).toString().includes("built in")&&(o-=1,o||(b.command.stdout.removeListener("data",e),g?.command.stdout.removeListener("data",e),r(v.isProd,v.viteConfig),a?.()))};return b.command.stdout.on("data",e),void g?.command.stdout.on("data",e)}c&&v.unlockRobots(),r(v.isProd,v.viteConfig),a?.();const h=t.dim(`${t.yellowBright(S.join(","))} built in ${t.reset(t.bold(Math.ceil(e.now()-f)))} ms`);console.info(`\n ${t.green(`${t.bold(s.toUpperCase())}`)} ${h} ${v.isProd?"":t.redBright(`NODE_ENV=${v.nodeEnv}`)}\n`)}export{a as default};
1
+ import o from"node:child_process";import{performance as e}from"node:perf_hooks";import t from"chalk";import i from"./vite-reset-cache.js";import s from"../constants/cli-name.js";import{createDevMarker as r}from"../helpers/dev-marker.js";import n from"../services/build.js";async function a({onFinish:a,isOnlyClient:l=!1,isWatch:d=!1,isUnlockRobots:c=!1,isEject:m=!1,clientOptions:p="",serverOptions:u="",mode:O=""}){const f=e.now(),v=new n({mode:O}),S=["client"],$=new AbortController,_=O?`--mode ${O}`:"";await v.makeConfig(),await i(),v.clearBuildFolder();const b=v.promisifyProcess(o.spawn(`vite build ${p} --emptyOutDir --outDir ${v.outDir}/client ${_}`,{signal:$.signal,stdio:[process.stdin,"pipe",process.stderr],shell:!0,env:{...process.env,FORCE_COLOR:"2",SSR_BOOST_IS_SSR:l?"0":"1",SSR_BOOST_ACTION:global.viteBoostAction}}));let g;if(d||await b,l||(g=v.promisifyProcess(o.spawn(`vite build ${u} --emptyOutDir --outDir ${v.outDir}/server --ssr ${v.serverFile} ${_}`,{signal:$.signal,stdio:[process.stdin,"pipe",process.stderr],shell:!0,env:{...process.env,FORCE_COLOR:"2",SSR_BOOST_IS_SSR:l?"0":"1",SSR_BOOST_ACTION:global.viteBoostAction}})),d||(await g,await v.buildManifest(),m&&v.eject()),S.push("server")),d){process.on("exit",(()=>{$.abort()}));let o=l?1:2;const e=t=>{Buffer.from(t).toString().includes("built in")&&(o-=1,o||(b.command.stdout.removeListener("data",e),g?.command.stdout.removeListener("data",e),r(v.isProd,v.viteConfig),a?.()))};return b.command.stdout.on("data",e),void g?.command.stdout.on("data",e)}c&&v.unlockRobots(),r(v.isProd,v.viteConfig),a?.();const h=Math.ceil(e.now()-f),w=h>1e3?(h/1e3).toFixed(2):h,C=h>1e3?"s":"ms",R=t.dim(`${t.yellowBright(S.join(","))} built in ${t.reset(t.bold(w))} ${C}`);console.info(`\n ${t.green(`${t.bold(s.toUpperCase())}`)} ${R} ${v.isProd?"":t.redBright(`NODE_ENV=${v.nodeEnv}`)}\n`)}export{a as default};
2
2
  //# sourceMappingURL=build.js.map
package/cli/build.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sources":["../../src/cli/build.ts"],"sourcesContent":["import childProcess from 'node:child_process';\nimport { performance } from 'node:perf_hooks';\nimport chalk from 'chalk';\nimport viteResetCache from '@cli/vite-reset-cache';\nimport cliName from '@constants/cli-name';\nimport { createDevMarker } from '@helpers/dev-marker';\nimport Build from '@services/build';\n\ninterface IBuildParams {\n isOnlyClient?: boolean;\n isWatch?: boolean;\n isEject?: boolean;\n isUnlockRobots?: boolean;\n clientOptions?: string;\n serverOptions?: string;\n mode?: string;\n onFinish?: () => void;\n}\n\n/**\n * Build production application\n */\nasync function build({\n onFinish,\n isOnlyClient = false,\n isWatch = false,\n isUnlockRobots = false,\n isEject = false,\n clientOptions = '',\n serverOptions = '',\n mode = '',\n}: IBuildParams): Promise<void> {\n const perfStart = performance.now();\n const buildService = new Build({ mode });\n const types = ['client'];\n const controller = new AbortController();\n const modeOpt = mode ? `--mode ${mode}` : '';\n\n await buildService.makeConfig();\n\n // this is required step - build with different env may cause problems\n await viteResetCache();\n buildService.clearBuildFolder();\n\n /**\n * Build client\n */\n const clientProcess = buildService.promisifyProcess(\n childProcess.spawn(\n `vite build ${clientOptions} --emptyOutDir --outDir ${buildService.outDir}/client ${modeOpt}`,\n {\n signal: controller.signal,\n stdio: [process.stdin, 'pipe', process.stderr],\n shell: true,\n env: {\n ...process.env,\n FORCE_COLOR: '2',\n SSR_BOOST_IS_SSR: isOnlyClient ? '0' : '1',\n SSR_BOOST_ACTION: global.viteBoostAction,\n },\n },\n ),\n );\n\n if (!isWatch) {\n await clientProcess;\n }\n\n let serverProcess: Promise<unknown> | undefined;\n\n /**\n * Build server\n */\n if (!isOnlyClient) {\n serverProcess = buildService.promisifyProcess(\n childProcess.spawn(\n `vite build ${serverOptions} --emptyOutDir --outDir ${buildService.outDir}/server --ssr ${buildService.serverFile} ${modeOpt}`,\n {\n signal: controller.signal,\n stdio: [process.stdin, 'pipe', process.stderr],\n shell: true,\n env: {\n ...process.env,\n FORCE_COLOR: '2',\n SSR_BOOST_IS_SSR: isOnlyClient ? '0' : '1',\n SSR_BOOST_ACTION: global.viteBoostAction,\n },\n },\n ),\n );\n\n if (!isWatch) {\n await serverProcess;\n await buildService.buildManifest();\n\n if (isEject) {\n buildService.eject();\n }\n }\n\n types.push('server');\n }\n\n /**\n * Preview mode\n */\n if (isWatch) {\n process.on('exit', () => {\n controller.abort();\n });\n\n let buildCount = isOnlyClient ? 1 : 2;\n const listener = (buff: Uint8Array): void => {\n const msg = Buffer.from(buff).toString();\n\n if (msg.includes('built in')) {\n buildCount -= 1;\n\n if (!buildCount) {\n clientProcess['command'].stdout.removeListener('data', listener);\n serverProcess?.['command'].stdout.removeListener('data', listener);\n createDevMarker(buildService.isProd, buildService.viteConfig);\n onFinish?.();\n }\n }\n };\n\n /**\n * Listen output for call onFinish\n */\n clientProcess['command'].stdout.on('data', listener);\n serverProcess?.['command'].stdout.on('data', listener);\n\n return;\n }\n\n if (isUnlockRobots) {\n buildService.unlockRobots();\n }\n\n createDevMarker(buildService.isProd, buildService.viteConfig);\n onFinish?.();\n\n const buildDurationString = chalk.dim(\n `${chalk.yellowBright(types.join(','))} built in ${chalk.reset(\n chalk.bold(Math.ceil(performance.now() - perfStart)),\n )} ms`,\n );\n\n console.info(\n `\\n ${chalk.green(`${chalk.bold(cliName.toUpperCase())}`)} ${buildDurationString} ${\n buildService.isProd ? '' : chalk.redBright(`NODE_ENV=${buildService.nodeEnv}`)\n }\\n`,\n );\n}\n\nexport default build;\n"],"names":["async","build","onFinish","isOnlyClient","isWatch","isUnlockRobots","isEject","clientOptions","serverOptions","mode","perfStart","performance","now","buildService","Build","types","controller","AbortController","modeOpt","makeConfig","viteResetCache","clearBuildFolder","clientProcess","promisifyProcess","childProcess","spawn","outDir","signal","stdio","process","stdin","stderr","shell","env","FORCE_COLOR","SSR_BOOST_IS_SSR","SSR_BOOST_ACTION","global","viteBoostAction","serverProcess","serverFile","buildManifest","eject","push","on","abort","buildCount","listener","buff","Buffer","from","toString","includes","stdout","removeListener","createDevMarker","isProd","viteConfig","unlockRobots","buildDurationString","chalk","dim","yellowBright","join","reset","bold","Math","ceil","console","info","green","cliName","toUpperCase","redBright","nodeEnv"],"mappings":"iRAsBAA,eAAeC,GAAMC,SACnBA,EAAQC,aACRA,GAAe,EAAKC,QACpBA,GAAU,EAAKC,eACfA,GAAiB,EAAKC,QACtBA,GAAU,EAAKC,cACfA,EAAgB,GAAEC,cAClBA,EAAgB,GAAEC,KAClBA,EAAO,KAEP,MAAMC,EAAYC,EAAYC,MACxBC,EAAe,IAAIC,EAAM,CAAEL,SAC3BM,EAAQ,CAAC,UACTC,EAAa,IAAIC,gBACjBC,EAAUT,EAAO,UAAUA,IAAS,SAEpCI,EAAaM,mBAGbC,IACNP,EAAaQ,mBAKb,MAAMC,EAAgBT,EAAaU,iBACjCC,EAAaC,MACX,cAAclB,4BAAwCM,EAAaa,iBAAiBR,IACpF,CACES,OAAQX,EAAWW,OACnBC,MAAO,CAACC,QAAQC,MAAO,OAAQD,QAAQE,QACvCC,OAAO,EACPC,IAAK,IACAJ,QAAQI,IACXC,YAAa,IACbC,iBAAkBhC,EAAe,IAAM,IACvCiC,iBAAkBC,OAAOC,oBAUjC,IAAIC,EAsCJ,GA1CKnC,SACGkB,EAQHnB,IACHoC,EAAgB1B,EAAaU,iBAC3BC,EAAaC,MACX,cAAcjB,4BAAwCK,EAAaa,uBAAuBb,EAAa2B,cAActB,IACrH,CACES,OAAQX,EAAWW,OACnBC,MAAO,CAACC,QAAQC,MAAO,OAAQD,QAAQE,QACvCC,OAAO,EACPC,IAAK,IACAJ,QAAQI,IACXC,YAAa,IACbC,iBAAkBhC,EAAe,IAAM,IACvCiC,iBAAkBC,OAAOC,oBAM5BlC,UACGmC,QACA1B,EAAa4B,gBAEfnC,GACFO,EAAa6B,SAIjB3B,EAAM4B,KAAK,WAMTvC,EAAS,CACXyB,QAAQe,GAAG,QAAQ,KACjB5B,EAAW6B,OAAO,IAGpB,IAAIC,EAAa3C,EAAe,EAAI,EACpC,MAAM4C,EAAYC,IACJC,OAAOC,KAAKF,GAAMG,WAEtBC,SAAS,cACfN,GAAc,EAETA,IACHxB,EAAuB,QAAE+B,OAAOC,eAAe,OAAQP,GACvDR,GAAyB,QAAEc,OAAOC,eAAe,OAAQP,GACzDQ,EAAgB1C,EAAa2C,OAAQ3C,EAAa4C,YAClDvD,OAEH,EASH,OAHAoB,EAAuB,QAAE+B,OAAOT,GAAG,OAAQG,QAC3CR,GAAyB,QAAEc,OAAOT,GAAG,OAAQG,EAG9C,CAEG1C,GACFQ,EAAa6C,eAGfH,EAAgB1C,EAAa2C,OAAQ3C,EAAa4C,YAClDvD,MAEA,MAAMyD,EAAsBC,EAAMC,IAChC,GAAGD,EAAME,aAAa/C,EAAMgD,KAAK,kBAAkBH,EAAMI,MACvDJ,EAAMK,KAAKC,KAAKC,KAAKxD,EAAYC,MAAQF,WAI7C0D,QAAQC,KACN,OAAOT,EAAMU,MAAM,GAAGV,EAAMK,KAAKM,EAAQC,sBAAsBb,KAC7D9C,EAAa2C,OAAS,GAAKI,EAAMa,UAAU,YAAY5D,EAAa6D,eAG1E"}
1
+ {"version":3,"file":"build.js","sources":["../../src/cli/build.ts"],"sourcesContent":["import childProcess from 'node:child_process';\nimport { performance } from 'node:perf_hooks';\nimport chalk from 'chalk';\nimport viteResetCache from '@cli/vite-reset-cache';\nimport cliName from '@constants/cli-name';\nimport { createDevMarker } from '@helpers/dev-marker';\nimport Build from '@services/build';\n\ninterface IBuildParams {\n isOnlyClient?: boolean;\n isWatch?: boolean;\n isEject?: boolean;\n isUnlockRobots?: boolean;\n clientOptions?: string;\n serverOptions?: string;\n mode?: string;\n onFinish?: () => void;\n}\n\n/**\n * Build production application\n */\nasync function build({\n onFinish,\n isOnlyClient = false,\n isWatch = false,\n isUnlockRobots = false,\n isEject = false,\n clientOptions = '',\n serverOptions = '',\n mode = '',\n}: IBuildParams): Promise<void> {\n const perfStart = performance.now();\n const buildService = new Build({ mode });\n const types = ['client'];\n const controller = new AbortController();\n const modeOpt = mode ? `--mode ${mode}` : '';\n\n await buildService.makeConfig();\n\n // this is required step - build with different env may cause problems\n await viteResetCache();\n buildService.clearBuildFolder();\n\n /**\n * Build client\n */\n const clientProcess = buildService.promisifyProcess(\n childProcess.spawn(\n `vite build ${clientOptions} --emptyOutDir --outDir ${buildService.outDir}/client ${modeOpt}`,\n {\n signal: controller.signal,\n stdio: [process.stdin, 'pipe', process.stderr],\n shell: true,\n env: {\n ...process.env,\n FORCE_COLOR: '2',\n SSR_BOOST_IS_SSR: isOnlyClient ? '0' : '1',\n SSR_BOOST_ACTION: global.viteBoostAction,\n },\n },\n ),\n );\n\n if (!isWatch) {\n await clientProcess;\n }\n\n let serverProcess: Promise<unknown> | undefined;\n\n /**\n * Build server\n */\n if (!isOnlyClient) {\n serverProcess = buildService.promisifyProcess(\n childProcess.spawn(\n `vite build ${serverOptions} --emptyOutDir --outDir ${buildService.outDir}/server --ssr ${buildService.serverFile} ${modeOpt}`,\n {\n signal: controller.signal,\n stdio: [process.stdin, 'pipe', process.stderr],\n shell: true,\n env: {\n ...process.env,\n FORCE_COLOR: '2',\n SSR_BOOST_IS_SSR: isOnlyClient ? '0' : '1',\n SSR_BOOST_ACTION: global.viteBoostAction,\n },\n },\n ),\n );\n\n if (!isWatch) {\n await serverProcess;\n await buildService.buildManifest();\n\n if (isEject) {\n buildService.eject();\n }\n }\n\n types.push('server');\n }\n\n /**\n * Preview mode\n */\n if (isWatch) {\n process.on('exit', () => {\n controller.abort();\n });\n\n let buildCount = isOnlyClient ? 1 : 2;\n const listener = (buff: Uint8Array): void => {\n const msg = Buffer.from(buff).toString();\n\n if (msg.includes('built in')) {\n buildCount -= 1;\n\n if (!buildCount) {\n clientProcess['command'].stdout.removeListener('data', listener);\n serverProcess?.['command'].stdout.removeListener('data', listener);\n createDevMarker(buildService.isProd, buildService.viteConfig);\n onFinish?.();\n }\n }\n };\n\n /**\n * Listen output for call onFinish\n */\n clientProcess['command'].stdout.on('data', listener);\n serverProcess?.['command'].stdout.on('data', listener);\n\n return;\n }\n\n if (isUnlockRobots) {\n buildService.unlockRobots();\n }\n\n createDevMarker(buildService.isProd, buildService.viteConfig);\n onFinish?.();\n\n const durationMs = Math.ceil(performance.now() - perfStart);\n const duration = durationMs > 1000 ? (durationMs / 1000).toFixed(2) : durationMs;\n const units = durationMs > 1000 ? 's' : 'ms';\n\n const buildDurationString = chalk.dim(\n `${chalk.yellowBright(types.join(','))} built in ${chalk.reset(chalk.bold(duration))} ${units}`,\n );\n\n console.info(\n `\\n ${chalk.green(`${chalk.bold(cliName.toUpperCase())}`)} ${buildDurationString} ${\n buildService.isProd ? '' : chalk.redBright(`NODE_ENV=${buildService.nodeEnv}`)\n }\\n`,\n );\n}\n\nexport default build;\n"],"names":["async","build","onFinish","isOnlyClient","isWatch","isUnlockRobots","isEject","clientOptions","serverOptions","mode","perfStart","performance","now","buildService","Build","types","controller","AbortController","modeOpt","makeConfig","viteResetCache","clearBuildFolder","clientProcess","promisifyProcess","childProcess","spawn","outDir","signal","stdio","process","stdin","stderr","shell","env","FORCE_COLOR","SSR_BOOST_IS_SSR","SSR_BOOST_ACTION","global","viteBoostAction","serverProcess","serverFile","buildManifest","eject","push","on","abort","buildCount","listener","buff","Buffer","from","toString","includes","stdout","removeListener","createDevMarker","isProd","viteConfig","unlockRobots","durationMs","Math","ceil","duration","toFixed","units","buildDurationString","chalk","dim","yellowBright","join","reset","bold","console","info","green","cliName","toUpperCase","redBright","nodeEnv"],"mappings":"iRAsBAA,eAAeC,GAAMC,SACnBA,EAAQC,aACRA,GAAe,EAAKC,QACpBA,GAAU,EAAKC,eACfA,GAAiB,EAAKC,QACtBA,GAAU,EAAKC,cACfA,EAAgB,GAAEC,cAClBA,EAAgB,GAAEC,KAClBA,EAAO,KAEP,MAAMC,EAAYC,EAAYC,MACxBC,EAAe,IAAIC,EAAM,CAAEL,SAC3BM,EAAQ,CAAC,UACTC,EAAa,IAAIC,gBACjBC,EAAUT,EAAO,UAAUA,IAAS,SAEpCI,EAAaM,mBAGbC,IACNP,EAAaQ,mBAKb,MAAMC,EAAgBT,EAAaU,iBACjCC,EAAaC,MACX,cAAclB,4BAAwCM,EAAaa,iBAAiBR,IACpF,CACES,OAAQX,EAAWW,OACnBC,MAAO,CAACC,QAAQC,MAAO,OAAQD,QAAQE,QACvCC,OAAO,EACPC,IAAK,IACAJ,QAAQI,IACXC,YAAa,IACbC,iBAAkBhC,EAAe,IAAM,IACvCiC,iBAAkBC,OAAOC,oBAUjC,IAAIC,EAsCJ,GA1CKnC,SACGkB,EAQHnB,IACHoC,EAAgB1B,EAAaU,iBAC3BC,EAAaC,MACX,cAAcjB,4BAAwCK,EAAaa,uBAAuBb,EAAa2B,cAActB,IACrH,CACES,OAAQX,EAAWW,OACnBC,MAAO,CAACC,QAAQC,MAAO,OAAQD,QAAQE,QACvCC,OAAO,EACPC,IAAK,IACAJ,QAAQI,IACXC,YAAa,IACbC,iBAAkBhC,EAAe,IAAM,IACvCiC,iBAAkBC,OAAOC,oBAM5BlC,UACGmC,QACA1B,EAAa4B,gBAEfnC,GACFO,EAAa6B,SAIjB3B,EAAM4B,KAAK,WAMTvC,EAAS,CACXyB,QAAQe,GAAG,QAAQ,KACjB5B,EAAW6B,OAAO,IAGpB,IAAIC,EAAa3C,EAAe,EAAI,EACpC,MAAM4C,EAAYC,IACJC,OAAOC,KAAKF,GAAMG,WAEtBC,SAAS,cACfN,GAAc,EAETA,IACHxB,EAAuB,QAAE+B,OAAOC,eAAe,OAAQP,GACvDR,GAAyB,QAAEc,OAAOC,eAAe,OAAQP,GACzDQ,EAAgB1C,EAAa2C,OAAQ3C,EAAa4C,YAClDvD,OAEH,EASH,OAHAoB,EAAuB,QAAE+B,OAAOT,GAAG,OAAQG,QAC3CR,GAAyB,QAAEc,OAAOT,GAAG,OAAQG,EAG9C,CAEG1C,GACFQ,EAAa6C,eAGfH,EAAgB1C,EAAa2C,OAAQ3C,EAAa4C,YAClDvD,MAEA,MAAMyD,EAAaC,KAAKC,KAAKlD,EAAYC,MAAQF,GAC3CoD,EAAWH,EAAa,KAAQA,EAAa,KAAMI,QAAQ,GAAKJ,EAChEK,EAAQL,EAAa,IAAO,IAAM,KAElCM,EAAsBC,EAAMC,IAChC,GAAGD,EAAME,aAAarD,EAAMsD,KAAK,kBAAkBH,EAAMI,MAAMJ,EAAMK,KAAKT,OAAcE,KAG1FQ,QAAQC,KACN,OAAOP,EAAMQ,MAAM,GAAGR,EAAMK,KAAKI,EAAQC,sBAAsBX,KAC7DpD,EAAa2C,OAAS,GAAKU,EAAMW,UAAU,YAAYhE,EAAaiE,eAG1E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lomray/vite-ssr-boost",
3
- "version": "1.0.0-beta.29",
3
+ "version": "1.0.0-beta.30",
4
4
  "description": "Vite plugin for create awesome SSR or SPA applications on React.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -1,2 +1,2 @@
1
- import t from"node:fs";import e from"node:path";import s from"chalk";import i from"./prepare-server.js";import r from"./server-config.js";var n;!function(t){t.style="style",t.script="script",t.image="image",t.font="font"}(n||(n={}));const o="\r\n";class a{static instance=null;config;root;buildDir;manifestName="manifest.json";assetsManifest="assets-manifest.json";viteAliases;routesAssets=null;constructor(t,{buildDir:e,viteAliases:s}={}){this.config=t,this.root=t.getParams().root,this.buildDir=e,this.viteAliases=s??t.getVite()?.config?.resolve.alias}static get(t,e={}){return null===a.instance&&(a.instance=new a(t,e)),a.instance}getAssetsManifestFile(){return`${e.resolve(this.root,this.buildDir||"")}/server/${this.assetsManifest}`}loadClientManifest(){const s=e.resolve(this.root,`${this.buildDir||""}/client/${this.manifestName}`);if(!t.existsSync(s))return{};const i=JSON.parse(t.readFileSync(s,{encoding:"utf-8"}));return t.rmSync(s),i}loadAssetsManifest(){if(null!==this.routesAssets)return this.routesAssets;const e=this.getAssetsManifestFile();return t.existsSync(e)?(this.routesAssets=JSON.parse(t.readFileSync(e,{encoding:"utf-8"})),this.routesAssets):{}}async getRoutesIds(t,e){const s={};for(const i in t){const r=t[i],n=[e,i].filter(Boolean).join("-");if(r.lazy){const t=await r.lazy();s[n]=this.normalizeRoutePath(t?.pathId)}else r.children&&Object.assign(s,await this.getRoutesIds(r.children,n))}return s}async buildRoutesManifest(e){const s=i.init(r.init({isProd:!0})),n=this.loadClientManifest(),{routes:o}=await s.loadEntrypoint(!1),a=await this.getRoutesIds(o),l=this.getRouteImportPostfix(),c={};Object.entries(a).forEach((([t,s])=>{const i=l.find((t=>void 0!==n[`${s}${t}`])),r=n[`${s}${i||""}`],o=[...r?.assets??[],...r?.css??[],r.file,...(e?r?.imports??[]:[]).map((t=>n[t]?.file))].filter((t=>t&&this.getAssetType(t))).map((t=>`/${t}`));o&&(c[t]=o)})),t.writeFileSync(this.getAssetsManifestFile(),JSON.stringify(c,null,2),{encoding:"utf-8"})}getAliases(){const t={};return this.viteAliases?.forEach((({find:e,replacement:s})=>{"string"==typeof e&&(t[e]=s)})),t}getRouteImportPostfix(){return["","/index"].map((t=>["",".js",".ts",".tsx"].map((e=>`${t}${e}`)))).flat()}normalizeRoutePath(t,s=!1){if(!t)return;let i="";if(t.startsWith("./")||t.startsWith("../"))i=e.resolve(this.root,t);else{const e=this.getAliases(),[s]=t.split("/");e[s]&&(i=t.replace(s,e[s]))}return i=i.split(e.win32.sep).join(e.posix.sep),s?i:i.replace(this.root,"").replace(/^\/|\/$/g,"")}getAssets(t){if(this.config.getVite())return this.getAssetsDev(t);const e=t?.map((({route:t})=>t.id)).filter(Boolean)??[];if(!e.length)return[];const s=this.loadAssetsManifest();return e.map((t=>s[t])).filter(Boolean).flat().sort(((t,e)=>{const s=this.getAssetWeight(t),i=this.getAssetWeight(e);return s===i?0:s-i})).map((t=>({type:this.getAssetType(t),url:t})))}getAssetsDev(t){const e=t?.map((({route:t})=>this.normalizeRoutePath(t?.pathId,!0))).filter(Boolean)??[];if(!e.length)return[];let s={};const i=this.getRouteImportPostfix();return[`${this.root}/${this.config.getPluginConfig()?.clientFile??"client.ts"}`,...e].forEach((t=>{for(const e of i){const i=this.config.getVite()?.moduleGraph.getModuleById(`${t}${e}`);if(i){s={...s,...this.getModuleAssets(i)};break}}})),Object.values(s)}getModuleAssets(t){if(!t?.clientImportedModules.size)return{};let e={};return t.clientImportedModules.forEach((t=>{const{file:i,clientImportedModules:r,transformResult:o}=t,a=i?.split(".").at(-1);if(i&&a&&["css","scss"].includes(a)){const t=o?.code.match(/__vite__css\s+=\s+"(?<css>.+)"/)?.groups?.css;if(t)try{e[i]={type:n.style,url:i,content:JSON.parse(`{"style": "${t}"}`).style}}catch(t){console.warn(s.yellowBright("Failed to parse style: ",i))}}else r.size&&(e={...e,...this.getModuleAssets(t)})})),e}getAssetWeight(t){switch(this.getAssetType(t)){case"style":return 1;case"script":return 2;default:return 3}}getAssetType(t){const e=t.split(".").at(-1)?.toLowerCase();switch(e){case"css":case"scss":return n.style;case"js":return n.script;case"svg":case"jpg":case"jpeg":case"png":case"webp":case"gif":case"ico":return n.image;case"ttf":case"otf":case"woff":case"woff2":return n.font;default:return null}}writeEarlyHits(t,e){e.write(`HTTP/1.1 103 Early Hints${o}`),t.forEach((({type:t,url:s})=>{t&&["style","script"].includes(t)&&e.write(`Link: <${s}>; rel=preload; as=${t}${o}`)})),e.write(o)}injectAssets({routerContext:t,html:e,res:s,hasEarlyHints:i=!1}){const r=this.getAssets(t?.matches),n=r.map((({type:t,url:e,content:s=""})=>{switch(t){case"style":return this.config.getVite()?`<style data-vite-dev-id="${e}">${s}</style>`:`<link rel="stylesheet" href="${e}">`;case"script":return`<script async type="module" src="${e}"><\/script>`}return null})).filter(Boolean);e.header=e.header.replace("</head>",`${n.join("\n")}</head>`),i&&n.length&&s.socket&&this.writeEarlyHits(r,s.socket)}}export{a as default};
1
+ import t from"node:fs";import e from"node:path";import s from"chalk";import i from"./prepare-server.js";import r from"./server-config.js";var n;!function(t){t.style="style",t.script="script",t.image="image",t.font="font"}(n||(n={}));const o="\r\n";class a{static instance=null;config;root;buildDir;manifestName="manifest.json";assetsManifest="assets-manifest.json";viteAliases;routesAssets=null;constructor(t,{buildDir:e,viteAliases:s}={}){this.config=t,this.root=t.getParams().root,this.buildDir=e,this.viteAliases=s??t.getVite()?.config?.resolve.alias}static get(t,e={}){return null===a.instance&&(a.instance=new a(t,e)),a.instance}getAssetsManifestFile(){return`${e.resolve(this.root,this.buildDir||"")}/server/${this.assetsManifest}`}loadClientManifest(){const s=e.resolve(this.root,`${this.buildDir||""}/client/${this.manifestName}`);if(!t.existsSync(s))return{};const i=JSON.parse(t.readFileSync(s,{encoding:"utf-8"}));return t.rmSync(s),i}loadAssetsManifest(){if(null!==this.routesAssets)return this.routesAssets;const e=this.getAssetsManifestFile();return t.existsSync(e)?(this.routesAssets=JSON.parse(t.readFileSync(e,{encoding:"utf-8"})),this.routesAssets):{}}async getRoutesIds(t,e){const i={};for(const r in t){const n=t[r],o=[e,r].filter(Boolean).join("-");if(n.lazy)try{const t=await n.lazy();i[o]=this.normalizeRoutePath(t?.pathId)}catch(t){console.error(s.red("Failed to load route:"),n.path,t)}else n.children&&Object.assign(i,await this.getRoutesIds(n.children,o))}return i}async buildRoutesManifest(e){const s=i.init(r.init({isProd:!0})),n=this.loadClientManifest(),{routes:o}=await s.loadEntrypoint(!1),a=await this.getRoutesIds(o),l=this.getRouteImportPostfix(),c={};Object.entries(a).forEach((([t,s])=>{const i=l.find((t=>void 0!==n[`${s}${t}`])),r=n[`${s}${i||""}`],o=[...r?.assets??[],...r?.css??[],r?.file,...(e?r?.imports??[]:[]).map((t=>n[t]?.file))].filter((t=>t&&this.getAssetType(t))).map((t=>`/${t}`));o&&(c[t]=o)})),t.writeFileSync(this.getAssetsManifestFile(),JSON.stringify(c,null,2),{encoding:"utf-8"})}getAliases(){const t={};return this.viteAliases?.forEach((({find:e,replacement:s})=>{"string"==typeof e&&(t[e]=s)})),t}getRouteImportPostfix(){return["","/index"].map((t=>["",".js",".ts",".tsx"].map((e=>`${t}${e}`)))).flat()}normalizeRoutePath(t,s=!1){if(!t)return;let i="";if(t.startsWith("./")||t.startsWith("../"))i=e.resolve(this.root,t);else{const e=this.getAliases(),[s]=t.split("/");e[s]&&(i=t.replace(s,e[s]))}return i=i.split(e.win32.sep).join(e.posix.sep),s?i:i.replace(this.root,"").replace(/^\/|\/$/g,"")}getAssets(t){if(this.config.getVite())return this.getAssetsDev(t);const e=t?.map((({route:t})=>t.id)).filter(Boolean)??[];if(!e.length)return[];const s=this.loadAssetsManifest();return e.map((t=>s[t])).filter(Boolean).flat().sort(((t,e)=>{const s=this.getAssetWeight(t),i=this.getAssetWeight(e);return s===i?0:s-i})).map((t=>({type:this.getAssetType(t),url:t})))}getAssetsDev(t){const e=t?.map((({route:t})=>this.normalizeRoutePath(t?.pathId,!0))).filter(Boolean)??[];if(!e.length)return[];let s={};const i=this.getRouteImportPostfix();return[`${this.root}/${this.config.getPluginConfig()?.clientFile??"client.ts"}`,...e].forEach((t=>{for(const e of i){const i=this.config.getVite()?.moduleGraph.getModuleById(`${t}${e}`);if(i){s={...s,...this.getModuleAssets(i)};break}}})),Object.values(s)}getModuleAssets(t){if(!t?.clientImportedModules.size)return{};let e={};return t.clientImportedModules.forEach((t=>{const{file:i,clientImportedModules:r,transformResult:o}=t,a=i?.split(".").at(-1);if(i&&a&&["css","scss"].includes(a)){const t=o?.code.match(/__vite__css\s+=\s+"(?<css>.+)"/)?.groups?.css;if(t)try{e[i]={type:n.style,url:i,content:JSON.parse(`{"style": "${t}"}`).style}}catch(t){console.warn(s.yellowBright("Failed to parse style: ",i))}}else r.size&&(e={...e,...this.getModuleAssets(t)})})),e}getAssetWeight(t){switch(this.getAssetType(t)){case"style":return 1;case"script":return 2;default:return 3}}getAssetType(t){const e=t.split(".").at(-1)?.toLowerCase();switch(e){case"css":case"scss":return n.style;case"js":return n.script;case"svg":case"jpg":case"jpeg":case"png":case"webp":case"gif":case"ico":return n.image;case"ttf":case"otf":case"woff":case"woff2":return n.font;default:return null}}writeEarlyHits(t,e){e.write(`HTTP/1.1 103 Early Hints${o}`),t.forEach((({type:t,url:s})=>{t&&["style","script"].includes(t)&&e.write(`Link: <${s}>; rel=preload; as=${t}${o}`)})),e.write(o)}injectAssets({routerContext:t,html:e,res:s,hasEarlyHints:i=!1}){const r=this.getAssets(t?.matches),n=r.map((({type:t,url:e,content:s=""})=>{switch(t){case"style":return this.config.getVite()?`<style data-vite-dev-id="${e}">${s}</style>`:`<link rel="stylesheet" href="${e}">`;case"script":return`<script async type="module" src="${e}"><\/script>`}return null})).filter(Boolean);e.header=e.header.replace("</head>",`${n.join("\n")}</head>`),i&&n.length&&s.socket&&this.writeEarlyHits(r,s.socket)}}export{a as default};
2
2
  //# sourceMappingURL=ssr-manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-manifest.js","sources":["../../src/services/ssr-manifest.ts"],"sourcesContent":["import fs from 'node:fs';\nimport type { Socket } from 'node:net';\nimport path from 'node:path';\nimport type { AgnosticDataRouteMatch } from '@remix-run/router/dist/utils';\nimport chalk from 'chalk';\nimport type { RouteObject } from 'react-router-dom';\nimport type { Alias, ModuleNode } from 'vite';\nimport type { IRequestContext } from '@node/render';\nimport PrepareServer from '@services/prepare-server';\nimport ServerConfig from '@services/server-config';\n\ninterface ISsrManifestParams {\n buildDir?: string;\n viteAliases?: Alias[];\n}\n\ninterface IManifest {\n [path: string]: {\n assets: string[];\n css: string[];\n file: string;\n imports: string[];\n };\n}\n\nenum AssetType {\n style = 'style',\n script = 'script',\n image = 'image',\n font = 'font',\n}\n\ninterface IAsset {\n type: AssetType;\n url: string;\n content?: string;\n}\n\nconst CRLF = '\\r\\n';\n\n/**\n * Working with SSR Manifest file\n */\nclass SsrManifest {\n /**\n * Singleton\n */\n protected static instance: SsrManifest | null = null;\n\n /**\n * Server config\n */\n protected readonly config: ServerConfig;\n\n /**\n * Project root path\n */\n protected readonly root: string;\n\n /**\n * Build dir\n */\n protected readonly buildDir?: string;\n\n /**\n * Client manifest file name\n */\n protected readonly manifestName = 'manifest.json';\n\n /**\n * Assets manifest file name\n */\n protected readonly assetsManifest = 'assets-manifest.json';\n\n /**\n * Vite resolve aliases\n */\n protected readonly viteAliases?: Alias[];\n\n /**\n * Loaded assets manifest file\n */\n protected routesAssets: Record<string, string[]> | null = null;\n\n /**\n * @constructor\n */\n protected constructor(config: ServerConfig, { buildDir, viteAliases }: ISsrManifestParams = {}) {\n this.config = config;\n this.root = config.getParams().root;\n this.buildDir = buildDir;\n this.viteAliases = viteAliases ?? config.getVite()?.config?.resolve.alias;\n }\n\n /**\n * Get singleton instance\n */\n public static get(config: ServerConfig, params: ISsrManifestParams = {}): SsrManifest {\n if (SsrManifest.instance === null) {\n SsrManifest.instance = new SsrManifest(config, params);\n }\n\n return SsrManifest.instance;\n }\n\n /**\n * Get assets manifest file name\n */\n protected getAssetsManifestFile(): string {\n const outDir = path.resolve(this.root, this.buildDir || '');\n\n return `${outDir}/server/${this.assetsManifest}`;\n }\n\n /**\n * Load client ssr manifest\n */\n protected loadClientManifest(): IManifest {\n const clientSsrManifest = path.resolve(\n this.root,\n `${this.buildDir || ''}/client/${this.manifestName}`,\n );\n\n if (!fs.existsSync(clientSsrManifest)) {\n return {};\n }\n\n const result = JSON.parse(\n fs.readFileSync(clientSsrManifest, { encoding: 'utf-8' }),\n ) as IManifest;\n\n fs.rmSync(clientSsrManifest);\n\n return result;\n }\n\n /**\n * Load assets manifest\n */\n protected loadAssetsManifest(): Record<string, string[]> {\n if (this.routesAssets !== null) {\n return this.routesAssets;\n }\n\n const manifestFile = this.getAssetsManifestFile();\n\n if (!fs.existsSync(manifestFile)) {\n return {};\n }\n\n this.routesAssets = JSON.parse(fs.readFileSync(manifestFile, { encoding: 'utf-8' })) as Record<\n string,\n string[]\n >;\n\n return this.routesAssets;\n }\n\n /**\n * Recursive walk routes and return id's with route import path\n */\n protected async getRoutesIds(\n routes: RouteObject[],\n index?: string,\n ): Promise<Record<string, string>> {\n const result = {};\n\n for (const routeIndex in routes) {\n const route = routes[routeIndex];\n const routeId = [index, routeIndex].filter(Boolean).join('-');\n\n if (route.lazy) {\n const resolvedRoute = await route.lazy();\n\n result[routeId] = this.normalizeRoutePath(resolvedRoute?.['pathId'] as string);\n } else if (route.children) {\n Object.assign(result, await this.getRoutesIds(route.children, routeId));\n }\n }\n\n return result;\n }\n\n /**\n * Build routes manifest file\n */\n public async buildRoutesManifest(shouldPreloadAssets: boolean): Promise<void> {\n const prepareServer = PrepareServer.init(ServerConfig.init({ isProd: true }));\n const manifest = this.loadClientManifest();\n const { routes } = await prepareServer.loadEntrypoint(false);\n const routesPaths = await this.getRoutesIds(routes as RouteObject[]);\n const postfixes = this.getRouteImportPostfix();\n\n const result = {};\n\n // find route assets\n Object.entries(routesPaths).forEach(([routeId, routePath]) => {\n const routePostfix = postfixes.find((postfix) => {\n const filePath = `${routePath}${postfix}`;\n\n return manifest[filePath] !== undefined;\n });\n const routeFile = `${routePath}${routePostfix || ''}`;\n const routeMeta = manifest[routeFile];\n const routeAssets = [\n ...(routeMeta?.assets ?? []),\n ...(routeMeta?.css ?? []),\n routeMeta.file,\n ...(shouldPreloadAssets ? routeMeta?.imports ?? [] : []).map(\n (nestedAsset) => manifest[nestedAsset]?.file,\n ),\n ]\n .filter(\n (asset) =>\n // keep only js,css,image,fonts files\n asset && this.getAssetType(asset),\n )\n .map((asset) => `/${asset}`);\n\n if (routeAssets) {\n result[routeId] = routeAssets;\n }\n });\n\n fs.writeFileSync(this.getAssetsManifestFile(), JSON.stringify(result, null, 2), {\n encoding: 'utf-8',\n });\n }\n\n /**\n * Get vite aliases\n */\n protected getAliases(): Record<string, string> {\n const aliases = {};\n\n this.viteAliases?.forEach(({ find, replacement }) => {\n if (typeof find !== 'string') {\n return;\n }\n\n aliases[find] = replacement;\n });\n\n return aliases;\n }\n\n /**\n * Return route postfix\n */\n protected getRouteImportPostfix(): string[] {\n return ['', '/index']\n .map((prefix) => ['', '.js', '.ts', '.tsx'].map((ext) => `${prefix}${ext}`))\n .flat();\n }\n\n /**\n * Normalized route path\n */\n protected normalizeRoutePath(routePath?: string, withRoot = false): string | undefined {\n if (!routePath) {\n return;\n }\n\n let fullPath = '';\n\n // relative import\n if (routePath.startsWith('./') || routePath.startsWith('../')) {\n fullPath = path.resolve(this.root, routePath);\n } else {\n // alias import\n const aliases = this.getAliases();\n // get alias\n const [routeAlias] = routePath.split('/');\n\n if (aliases[routeAlias]) {\n fullPath = routePath.replace(routeAlias, aliases[routeAlias]);\n }\n }\n\n // normalize slashes\n fullPath = fullPath.split(path.win32.sep).join(path.posix.sep);\n\n if (withRoot) {\n return fullPath;\n }\n\n return fullPath.replace(this.root, '').replace(/^\\/|\\/$/g, '');\n }\n\n /**\n * Get route assets\n */\n protected getAssets(routes?: AgnosticDataRouteMatch[]): IAsset[] {\n if (this.config.getVite()) {\n return this.getAssetsDev(routes);\n }\n\n const routeIds = routes?.map(({ route }) => route.id).filter(Boolean) ?? [];\n\n if (!routeIds.length) {\n return [];\n }\n\n const routesAssets = this.loadAssetsManifest();\n\n return routeIds\n .map((routeId) => routesAssets[routeId])\n .filter(Boolean)\n .flat()\n .sort((a, b) => {\n const aWeight = this.getAssetWeight(a);\n const bWeight = this.getAssetWeight(b);\n\n return aWeight === bWeight ? 0 : aWeight - bWeight;\n })\n .map((url) => ({\n type: this.getAssetType(url)!,\n url,\n }));\n }\n\n /**\n * Get development route assets\n */\n protected getAssetsDev(routes?: AgnosticDataRouteMatch[]): IAsset[] {\n const routeIds =\n (routes\n ?.map(({ route }) => this.normalizeRoutePath(route?.['pathId'] as string, true))\n .filter(Boolean) as string[]) ?? [];\n\n if (!routeIds.length) {\n return [];\n }\n\n let assets: { [id: string]: IAsset } = {};\n const postfixes = this.getRouteImportPostfix();\n const rootId = `${this.root}/${this.config.getPluginConfig()?.clientFile ?? 'client.ts'}`;\n\n [rootId, ...routeIds].forEach((moduleId) => {\n for (const ext of postfixes) {\n const module = this.config.getVite()?.moduleGraph.getModuleById(`${moduleId}${ext}`);\n\n if (module) {\n assets = { ...assets, ...this.getModuleAssets(module) };\n break;\n }\n }\n });\n\n return Object.values(assets);\n }\n\n /**\n * Get module assets\n */\n protected getModuleAssets(module?: ModuleNode): { [id: string]: IAsset } {\n if (!module?.clientImportedModules.size) {\n return {};\n }\n\n let assets: { [id: string]: IAsset } = {};\n\n module.clientImportedModules.forEach((subModule) => {\n const { file, clientImportedModules, transformResult } = subModule;\n const ext = file?.split('.').at(-1);\n\n if (file && ext && ['css', 'scss'].includes(ext)) {\n // @TODO investigate better method?\n const code = transformResult?.code.match(/__vite__css\\s+=\\s+\"(?<css>.+)\"/)?.groups?.css;\n\n if (code) {\n try {\n assets[file] = {\n type: AssetType.style,\n url: file,\n content: JSON.parse(`{\"style\": \"${code}\"}`).style,\n };\n } catch (e) {\n console.warn(chalk.yellowBright('Failed to parse style: ', file));\n }\n }\n } else if (clientImportedModules.size) {\n assets = {\n ...assets,\n ...this.getModuleAssets(subModule),\n };\n }\n });\n\n return assets;\n }\n\n /**\n * Get asset weight\n */\n protected getAssetWeight(asset: string): number {\n const type = this.getAssetType(asset);\n\n switch (type) {\n case 'style':\n return 1;\n\n case 'script':\n return 2;\n\n default:\n return 3;\n }\n }\n\n /**\n * Get asset type\n */\n protected getAssetType(asset: string): AssetType | null {\n const ext = asset.split('.').at(-1)?.toLowerCase();\n\n switch (ext) {\n case 'css':\n case 'scss':\n return AssetType.style;\n\n case 'js':\n return AssetType.script;\n\n case 'svg':\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'webp':\n case 'gif':\n case 'ico':\n return AssetType.image;\n\n case 'ttf':\n case 'otf':\n case 'woff':\n case 'woff2':\n return AssetType.font;\n\n default:\n return null;\n }\n }\n\n /**\n * Write 103 Early Hits header\n */\n public writeEarlyHits(assets: IAsset[], socket: Socket): void {\n socket.write(`HTTP/1.1 103 Early Hints${CRLF}`);\n assets.forEach(({ type, url }) => {\n if (!type || !['style', 'script'].includes(type)) {\n return;\n }\n\n socket.write(`Link: <${url}>; rel=preload; as=${type}${CRLF}`);\n });\n socket.write(CRLF);\n }\n\n /**\n * Inject route assets to head html\n */\n public injectAssets({ routerContext, html, res, hasEarlyHints = false }: IRequestContext): void {\n const assets = this.getAssets(routerContext?.matches);\n const htmlAssets = assets\n .map(({ type, url, content = '' }) => {\n switch (type) {\n case 'style':\n return this.config.getVite()\n ? `<style data-vite-dev-id=\"${url}\">${content}</style>`\n : `<link rel=\"stylesheet\" href=\"${url}\">`;\n\n case 'script':\n return `<script async type=\"module\" src=\"${url}\"></script>`;\n }\n\n return null;\n })\n .filter(Boolean);\n\n html.header = html.header.replace('</head>', `${htmlAssets.join('\\n')}</head>`);\n\n if (hasEarlyHints && htmlAssets.length && res.socket) {\n this.writeEarlyHits(assets, res.socket);\n }\n }\n}\n\nexport default SsrManifest;\n"],"names":["AssetType","CRLF","SsrManifest","static","config","root","buildDir","manifestName","assetsManifest","viteAliases","routesAssets","constructor","this","getParams","getVite","resolve","alias","params","instance","getAssetsManifestFile","path","loadClientManifest","clientSsrManifest","fs","existsSync","result","JSON","parse","readFileSync","encoding","rmSync","loadAssetsManifest","manifestFile","async","routes","index","routeIndex","route","routeId","filter","Boolean","join","lazy","resolvedRoute","normalizeRoutePath","children","Object","assign","getRoutesIds","shouldPreloadAssets","prepareServer","PrepareServer","init","ServerConfig","isProd","manifest","loadEntrypoint","routesPaths","postfixes","getRouteImportPostfix","entries","forEach","routePath","routePostfix","find","postfix","undefined","routeMeta","routeAssets","assets","css","file","imports","map","nestedAsset","asset","getAssetType","writeFileSync","stringify","getAliases","aliases","replacement","prefix","ext","flat","withRoot","fullPath","startsWith","routeAlias","split","replace","win32","sep","posix","getAssets","getAssetsDev","routeIds","id","length","sort","a","b","aWeight","getAssetWeight","bWeight","url","type","getPluginConfig","clientFile","moduleId","module","moduleGraph","getModuleById","getModuleAssets","values","clientImportedModules","size","subModule","transformResult","at","includes","code","match","groups","style","content","e","console","warn","chalk","yellowBright","toLowerCase","script","image","font","writeEarlyHits","socket","write","injectAssets","routerContext","html","res","hasEarlyHints","matches","htmlAssets","header"],"mappings":"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"}
1
+ {"version":3,"file":"ssr-manifest.js","sources":["../../src/services/ssr-manifest.ts"],"sourcesContent":["import fs from 'node:fs';\nimport type { Socket } from 'node:net';\nimport path from 'node:path';\nimport type { AgnosticDataRouteMatch } from '@remix-run/router/dist/utils';\nimport chalk from 'chalk';\nimport type { RouteObject } from 'react-router-dom';\nimport type { Alias, ModuleNode } from 'vite';\nimport type { IRequestContext } from '@node/render';\nimport PrepareServer from '@services/prepare-server';\nimport ServerConfig from '@services/server-config';\n\ninterface ISsrManifestParams {\n buildDir?: string;\n viteAliases?: Alias[];\n}\n\ninterface IManifest {\n [path: string]: {\n assets: string[];\n css: string[];\n file: string;\n imports: string[];\n };\n}\n\nenum AssetType {\n style = 'style',\n script = 'script',\n image = 'image',\n font = 'font',\n}\n\ninterface IAsset {\n type: AssetType;\n url: string;\n content?: string;\n}\n\nconst CRLF = '\\r\\n';\n\n/**\n * Working with SSR Manifest file\n */\nclass SsrManifest {\n /**\n * Singleton\n */\n protected static instance: SsrManifest | null = null;\n\n /**\n * Server config\n */\n protected readonly config: ServerConfig;\n\n /**\n * Project root path\n */\n protected readonly root: string;\n\n /**\n * Build dir\n */\n protected readonly buildDir?: string;\n\n /**\n * Client manifest file name\n */\n protected readonly manifestName = 'manifest.json';\n\n /**\n * Assets manifest file name\n */\n protected readonly assetsManifest = 'assets-manifest.json';\n\n /**\n * Vite resolve aliases\n */\n protected readonly viteAliases?: Alias[];\n\n /**\n * Loaded assets manifest file\n */\n protected routesAssets: Record<string, string[]> | null = null;\n\n /**\n * @constructor\n */\n protected constructor(config: ServerConfig, { buildDir, viteAliases }: ISsrManifestParams = {}) {\n this.config = config;\n this.root = config.getParams().root;\n this.buildDir = buildDir;\n this.viteAliases = viteAliases ?? config.getVite()?.config?.resolve.alias;\n }\n\n /**\n * Get singleton instance\n */\n public static get(config: ServerConfig, params: ISsrManifestParams = {}): SsrManifest {\n if (SsrManifest.instance === null) {\n SsrManifest.instance = new SsrManifest(config, params);\n }\n\n return SsrManifest.instance;\n }\n\n /**\n * Get assets manifest file name\n */\n protected getAssetsManifestFile(): string {\n const outDir = path.resolve(this.root, this.buildDir || '');\n\n return `${outDir}/server/${this.assetsManifest}`;\n }\n\n /**\n * Load client ssr manifest\n */\n protected loadClientManifest(): IManifest {\n const clientSsrManifest = path.resolve(\n this.root,\n `${this.buildDir || ''}/client/${this.manifestName}`,\n );\n\n if (!fs.existsSync(clientSsrManifest)) {\n return {};\n }\n\n const result = JSON.parse(\n fs.readFileSync(clientSsrManifest, { encoding: 'utf-8' }),\n ) as IManifest;\n\n fs.rmSync(clientSsrManifest);\n\n return result;\n }\n\n /**\n * Load assets manifest\n */\n protected loadAssetsManifest(): Record<string, string[]> {\n if (this.routesAssets !== null) {\n return this.routesAssets;\n }\n\n const manifestFile = this.getAssetsManifestFile();\n\n if (!fs.existsSync(manifestFile)) {\n return {};\n }\n\n this.routesAssets = JSON.parse(fs.readFileSync(manifestFile, { encoding: 'utf-8' })) as Record<\n string,\n string[]\n >;\n\n return this.routesAssets;\n }\n\n /**\n * Recursive walk routes and return id's with route import path\n */\n protected async getRoutesIds(\n routes: RouteObject[],\n index?: string,\n ): Promise<Record<string, string>> {\n const result = {};\n\n for (const routeIndex in routes) {\n const route = routes[routeIndex];\n const routeId = [index, routeIndex].filter(Boolean).join('-');\n\n if (route.lazy) {\n try {\n const resolvedRoute = await route.lazy();\n\n result[routeId] = this.normalizeRoutePath(resolvedRoute?.['pathId'] as string);\n } catch (e) {\n console.error(chalk.red('Failed to load route:'), route.path, e);\n }\n } else if (route.children) {\n Object.assign(result, await this.getRoutesIds(route.children, routeId));\n }\n }\n\n return result;\n }\n\n /**\n * Build routes manifest file\n */\n public async buildRoutesManifest(shouldPreloadAssets: boolean): Promise<void> {\n const prepareServer = PrepareServer.init(ServerConfig.init({ isProd: true }));\n const manifest = this.loadClientManifest();\n const { routes } = await prepareServer.loadEntrypoint(false);\n const routesPaths = await this.getRoutesIds(routes as RouteObject[]);\n const postfixes = this.getRouteImportPostfix();\n\n const result = {};\n\n // find route assets\n Object.entries(routesPaths).forEach(([routeId, routePath]) => {\n const routePostfix = postfixes.find((postfix) => {\n const filePath = `${routePath}${postfix}`;\n\n return manifest[filePath] !== undefined;\n });\n const routeFile = `${routePath}${routePostfix || ''}`;\n const routeMeta = manifest[routeFile];\n const routeAssets = [\n ...(routeMeta?.assets ?? []),\n ...(routeMeta?.css ?? []),\n routeMeta?.file,\n ...(shouldPreloadAssets ? routeMeta?.imports ?? [] : []).map(\n (nestedAsset) => manifest[nestedAsset]?.file,\n ),\n ]\n .filter(\n (asset) =>\n // keep only js,css,image,fonts files\n asset && this.getAssetType(asset),\n )\n .map((asset) => `/${asset}`);\n\n if (routeAssets) {\n result[routeId] = routeAssets;\n }\n });\n\n fs.writeFileSync(this.getAssetsManifestFile(), JSON.stringify(result, null, 2), {\n encoding: 'utf-8',\n });\n }\n\n /**\n * Get vite aliases\n */\n protected getAliases(): Record<string, string> {\n const aliases = {};\n\n this.viteAliases?.forEach(({ find, replacement }) => {\n if (typeof find !== 'string') {\n return;\n }\n\n aliases[find] = replacement;\n });\n\n return aliases;\n }\n\n /**\n * Return route postfix\n */\n protected getRouteImportPostfix(): string[] {\n return ['', '/index']\n .map((prefix) => ['', '.js', '.ts', '.tsx'].map((ext) => `${prefix}${ext}`))\n .flat();\n }\n\n /**\n * Normalized route path\n */\n protected normalizeRoutePath(routePath?: string, withRoot = false): string | undefined {\n if (!routePath) {\n return;\n }\n\n let fullPath = '';\n\n // relative import\n if (routePath.startsWith('./') || routePath.startsWith('../')) {\n fullPath = path.resolve(this.root, routePath);\n } else {\n // alias import\n const aliases = this.getAliases();\n // get alias\n const [routeAlias] = routePath.split('/');\n\n if (aliases[routeAlias]) {\n fullPath = routePath.replace(routeAlias, aliases[routeAlias]);\n }\n }\n\n // normalize slashes\n fullPath = fullPath.split(path.win32.sep).join(path.posix.sep);\n\n if (withRoot) {\n return fullPath;\n }\n\n return fullPath.replace(this.root, '').replace(/^\\/|\\/$/g, '');\n }\n\n /**\n * Get route assets\n */\n protected getAssets(routes?: AgnosticDataRouteMatch[]): IAsset[] {\n if (this.config.getVite()) {\n return this.getAssetsDev(routes);\n }\n\n const routeIds = routes?.map(({ route }) => route.id).filter(Boolean) ?? [];\n\n if (!routeIds.length) {\n return [];\n }\n\n const routesAssets = this.loadAssetsManifest();\n\n return routeIds\n .map((routeId) => routesAssets[routeId])\n .filter(Boolean)\n .flat()\n .sort((a, b) => {\n const aWeight = this.getAssetWeight(a);\n const bWeight = this.getAssetWeight(b);\n\n return aWeight === bWeight ? 0 : aWeight - bWeight;\n })\n .map((url) => ({\n type: this.getAssetType(url)!,\n url,\n }));\n }\n\n /**\n * Get development route assets\n */\n protected getAssetsDev(routes?: AgnosticDataRouteMatch[]): IAsset[] {\n const routeIds =\n (routes\n ?.map(({ route }) => this.normalizeRoutePath(route?.['pathId'] as string, true))\n .filter(Boolean) as string[]) ?? [];\n\n if (!routeIds.length) {\n return [];\n }\n\n let assets: { [id: string]: IAsset } = {};\n const postfixes = this.getRouteImportPostfix();\n const rootId = `${this.root}/${this.config.getPluginConfig()?.clientFile ?? 'client.ts'}`;\n\n [rootId, ...routeIds].forEach((moduleId) => {\n for (const ext of postfixes) {\n const module = this.config.getVite()?.moduleGraph.getModuleById(`${moduleId}${ext}`);\n\n if (module) {\n assets = { ...assets, ...this.getModuleAssets(module) };\n break;\n }\n }\n });\n\n return Object.values(assets);\n }\n\n /**\n * Get module assets\n */\n protected getModuleAssets(module?: ModuleNode): { [id: string]: IAsset } {\n if (!module?.clientImportedModules.size) {\n return {};\n }\n\n let assets: { [id: string]: IAsset } = {};\n\n module.clientImportedModules.forEach((subModule) => {\n const { file, clientImportedModules, transformResult } = subModule;\n const ext = file?.split('.').at(-1);\n\n if (file && ext && ['css', 'scss'].includes(ext)) {\n // @TODO investigate better method?\n const code = transformResult?.code.match(/__vite__css\\s+=\\s+\"(?<css>.+)\"/)?.groups?.css;\n\n if (code) {\n try {\n assets[file] = {\n type: AssetType.style,\n url: file,\n content: JSON.parse(`{\"style\": \"${code}\"}`).style,\n };\n } catch (e) {\n console.warn(chalk.yellowBright('Failed to parse style: ', file));\n }\n }\n } else if (clientImportedModules.size) {\n assets = {\n ...assets,\n ...this.getModuleAssets(subModule),\n };\n }\n });\n\n return assets;\n }\n\n /**\n * Get asset weight\n */\n protected getAssetWeight(asset: string): number {\n const type = this.getAssetType(asset);\n\n switch (type) {\n case 'style':\n return 1;\n\n case 'script':\n return 2;\n\n default:\n return 3;\n }\n }\n\n /**\n * Get asset type\n */\n protected getAssetType(asset: string): AssetType | null {\n const ext = asset.split('.').at(-1)?.toLowerCase();\n\n switch (ext) {\n case 'css':\n case 'scss':\n return AssetType.style;\n\n case 'js':\n return AssetType.script;\n\n case 'svg':\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'webp':\n case 'gif':\n case 'ico':\n return AssetType.image;\n\n case 'ttf':\n case 'otf':\n case 'woff':\n case 'woff2':\n return AssetType.font;\n\n default:\n return null;\n }\n }\n\n /**\n * Write 103 Early Hits header\n */\n public writeEarlyHits(assets: IAsset[], socket: Socket): void {\n socket.write(`HTTP/1.1 103 Early Hints${CRLF}`);\n assets.forEach(({ type, url }) => {\n if (!type || !['style', 'script'].includes(type)) {\n return;\n }\n\n socket.write(`Link: <${url}>; rel=preload; as=${type}${CRLF}`);\n });\n socket.write(CRLF);\n }\n\n /**\n * Inject route assets to head html\n */\n public injectAssets({ routerContext, html, res, hasEarlyHints = false }: IRequestContext): void {\n const assets = this.getAssets(routerContext?.matches);\n const htmlAssets = assets\n .map(({ type, url, content = '' }) => {\n switch (type) {\n case 'style':\n return this.config.getVite()\n ? `<style data-vite-dev-id=\"${url}\">${content}</style>`\n : `<link rel=\"stylesheet\" href=\"${url}\">`;\n\n case 'script':\n return `<script async type=\"module\" src=\"${url}\"></script>`;\n }\n\n return null;\n })\n .filter(Boolean);\n\n html.header = html.header.replace('</head>', `${htmlAssets.join('\\n')}</head>`);\n\n if (hasEarlyHints && htmlAssets.length && res.socket) {\n this.writeEarlyHits(assets, res.socket);\n }\n }\n}\n\nexport default SsrManifest;\n"],"names":["AssetType","CRLF","SsrManifest","static","config","root","buildDir","manifestName","assetsManifest","viteAliases","routesAssets","constructor","this","getParams","getVite","resolve","alias","params","instance","getAssetsManifestFile","path","loadClientManifest","clientSsrManifest","fs","existsSync","result","JSON","parse","readFileSync","encoding","rmSync","loadAssetsManifest","manifestFile","async","routes","index","routeIndex","route","routeId","filter","Boolean","join","lazy","resolvedRoute","normalizeRoutePath","e","console","error","chalk","red","children","Object","assign","getRoutesIds","shouldPreloadAssets","prepareServer","PrepareServer","init","ServerConfig","isProd","manifest","loadEntrypoint","routesPaths","postfixes","getRouteImportPostfix","entries","forEach","routePath","routePostfix","find","postfix","undefined","routeMeta","routeAssets","assets","css","file","imports","map","nestedAsset","asset","getAssetType","writeFileSync","stringify","getAliases","aliases","replacement","prefix","ext","flat","withRoot","fullPath","startsWith","routeAlias","split","replace","win32","sep","posix","getAssets","getAssetsDev","routeIds","id","length","sort","a","b","aWeight","getAssetWeight","bWeight","url","type","getPluginConfig","clientFile","moduleId","module","moduleGraph","getModuleById","getModuleAssets","values","clientImportedModules","size","subModule","transformResult","at","includes","code","match","groups","style","content","warn","yellowBright","toLowerCase","script","image","font","writeEarlyHits","socket","write","injectAssets","routerContext","html","res","hasEarlyHints","matches","htmlAssets","header"],"mappings":"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"}