You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
目前 webpack 模式下通过 "ssr": true 方式开启 ssr 能力,而在 vite 模式下目前是不支持的,期望 vite 模式下同样可以通过 "ssr": true 的方式一键启动 SSR 方案
具体设计
在 vite 模式下开启 ssr 能力后,新增一个插件 vite-plugin-ssr 完成 html 内容直出的工作:
functionvitePluginSSR(){return{name: 'vite-plugin-ssr',config(){// 完成 ssr 场景下的定制参数},configureServer: async(server)=>{// 定制 ssr 场景下的 server 处理consthandler=async(req,res,next)=>{try{constssrEntryPoint=awaitserver.ssrLoadModule(ssrEntry);// 执行页面 html 输出const{ html }=awaitssrEntryPoint.renderPage({ htmlTemplateContent, buildConfig, initialContext });res.setHeader('Content-Type','text/html')res.end(html);}catch(e){server.ssrFixStacktrace(e);}};return()=>server.middlewares.use(handler);}}}
原方案在插件层面重新创建一个 vite server,会导致多次预编译问题,并且在 dev 场景下仅依赖 ssrLoadModule 的 api 便可以完成 server 代码在 node 端执行的逻辑
存在问题
vite 模式下相关 SSR 能力
vite 支持通过 ssrModuleLoader 的方法,直接加载 node ssr 端代码,无须以 bundle 的形式执行:
背景
目前 webpack 模式下通过
"ssr": true
方式开启 ssr 能力,而在 vite 模式下目前是不支持的,期望 vite 模式下同样可以通过"ssr": true
的方式一键启动 SSR 方案具体设计
在 vite 模式下开启 ssr 能力后,新增一个插件
vite-plugin-ssr
完成 html 内容直出的工作:存在问题
vite 模式下相关 SSR 能力
vite 支持通过 ssrModuleLoader 的方法,直接加载 node ssr 端代码,无须以 bundle 的形式执行:
https://github.com/vitejs/vite/blob/4bdf5d70b52e4d7dd6436efd30e1046250d3bbfe/packages/vite/src/node/ssr/ssrModuleLoader.ts#L31-L36
但是该方法本身存在对于 cjs 的 exports 导出的不兼容,参考 vitejs/vite#2579
在 icejs 框架的 server.ts 运行下存在以下几个包会出现问题:
可选的解决方案是提前设置
vite.optimizeDeps.include
方式进行预编译支持 node 端执行的 esm 规范
目前 icejs 框架依赖的运行时代码库,仅导出了 esm 规范,但未添加
"type": "module"
或者 添加.mjs
的后缀,在 node 端无法以 esm 的方式执行。具体仓库如下:
对于上述的仓库,可以通过以下两种方式修复:
"type": "module"
,需要针对文件导入的地方添加 extension 参考 import without extension nodejs/node#30927 ) 推荐方式,需要兼顾底层包的规范vite.optimizeDeps.include
方式预编译成 esm 兼容模式node 端执行环境判断
在 webpack 链路下,ssr 的构建是额外的构建链路,因此在 ssr 链路中会设置
process.env.__IS_SERVER__
的变量,并且该变量将会耦合在运行时代码中ice/packages/plugin-ice-ssr/src/index.ts
Lines 76 to 78 in c2db0b5
对于 vite 而言,node 端执行和 client 端的请求转化均为统一 server 服务(期望上只会启动一个 viteServer),这样变造成代码运行时中依赖
process.env.__IS_SERVER__
是会造成误判,导致 CSR 过程的失败。解决方案:
在 ssrLoadModule 阶段执行设置
global.__IS_SERVER__ = true
,不在注入process.env.__IS_SERVER__
,并且在所有依赖process.env.__IS_SERVER__
的代码增加global.__IS_SERVER__
try { + global.__IS_SERVER__ = true const ssrEntryPoint = await server.ssrLoadModule(ssrEntry); // 执行页面 html 输出 const { html } = await ssrEntryPoint.renderPage({ htmlTemplateContent, buildConfig, initialContext });
The text was updated successfully, but these errors were encountered: