quasar.config.js
在这里可以配置一些SSR选项。 就像您希望客户端以SPA(单页应用程序-默认行为)或PWA(渐进式Web应用程序)接管一样。
return {
// ...
ssr: {
ssrPwaHtmlFilename: 'offline.html', // 不要使用index.html作为名称!
// 会搞乱SSR
extendSSRWebserverConf (esbuildConf) {},
// 添加/删除/更改
// 生产生成的package.json的属性
extendPackageJson (pkg) {
// 直接更换pkg属性;
// 不需要归还任何东西
},
pwa: false,
/**
* 手动序列化存储状态,
* 并且作为window.__INITIAL_STATE__自己提供给客户端(通过一个<script>标签)。
* (需要@quasar/app-vite v1.0.0-beta.14+)
*/
manualStoreSerialization: false,
/**
* 手动注入存储状态到ssrContext.state中
* (需要@quasar/app-app-vite v1.0.0-beta.14+)
*/
manualStoreSsrContextInjection: false,
/**
* 手动处理存储水化,而不是让Quasar CLI做。
* Pinia: store.state.value = window.__INITIAL_STATE__
* Vuex: store.replaceState(window.__INITIAL_STATE__)
*/
manualStoreHydration: false,
/**
* 手动调用$q.onSSRHydrated()而不是让Quasar CLI来做。
* 这宣布了客户端的代码应该接管。
*/
manualPostHydrationTrigger: false,
prodPort: 3000, // 生产服务器应该使用的默认端口
// (如果在运行时指定了 process.env.PORT,就会被取代)
middlewares: [
'render' //把这个作为最后一个
]
}
}
如果您决定使用PWA客户端接管(这是一个杀手组合),那么也会安装Quasar CLI PWA模式。 您可能还想查看Quasar PWA指南。 但最重要的是,请确保您阅读了使用PWA的SSR页。
如果你想篡改/src中UI的Vite配置:
// quasar.config.js
module.exports = function (ctx) {
return {
build: {
extendViteConf (viteConf, { isClient, isServer }) {
if (ctx.mode.ssr) {
// do something with ViteConf
}
}
}
}
}
手动触发存储水化
默认情况下,Quasar CLI会在客户端对Vuex存储(如果你使用它)进行水化。
然而,如果你希望自己手动进行水化,你需要设置quasar.config.js > ssr > manualStoreHydration: true。然后你需要自己调用store.replaceState(window.__INITIAL_STATE__)
。一个很好的例子是在启动文件中进行。
// some_boot_file
// 确保配置这个启动文件
// 只在客户端运行
export default ({ store }) => {
// Pinia写法
store.state.value = window.__INITIAL_STATE__
// Vuex写法
store.replaceState(window.__INITIAL_STATE__)
}
手动触发水化后
默认情况下,Quasar CLI会包装你的App组件,并在这个包装组件被安装时在客户端调用$q.onSSRHydrated()
。这是由客户端接管的时刻。你不需要配置任何东西来实现这一目标。
然而,如果你想覆盖这一时刻的发生,你需要设置quasar.config.js > ssr > manualPostHydrationTrigger: true。不管你的原因是什么(非常自定义的用例),这是一个手动触发水化后的例子。
// App.vue - Composition API
import { onMounted } from 'vue'
import { useQuasar } from 'quasar'
export default {
// ....
setup () {
// ...
const $q = useQuasar()
onMounted(() => {
$q.onSSRHydrated()
})
}
}
// App.vue - Options API
export default {
mounted () {
this.$q.onSSRHydrated()
}
}
Nodejs服务器
在Quasar项目中添加SSR模式意味着将创建一个新文件夹:/src-ssr
,其中包含SSR特定文件:
.
└── src-ssr/
├── middlewares/ # SSR middleware files
└── server.js # SSR webserver
你可以自由编辑这些文件。这两个文件夹中的每一个都在自己的文档页面中详细说明(查看左侧菜单)。
注意几件事:
这些文件在Node上下文中运行(Babel不会编译它们),因此请仅使用Node版本支持的ES6功能。 (https://node.green/)
如果从node_modules导入任何内容,请确保在package.json>“dependencies”中指定了该包,而在“devDependencies”中未指定。
/src-ssr/middlewares
是通过单独的Esbuild配置构建的。你可以通过quasar.config.js扩展这些文件的Esbuild配置。
return {
// ...
ssr: {
// ...
extendSSRWebserverConf (esbuildConf) {
// tamper with esbuildConf here
},
}
}
/src-ssr/server.js
文件在SSR Webserver页面有详细介绍。如果你需要支持无服务器功能,请特别阅读它。
帮助SEO
开发SSR而不是SPA的主要原因之一是要注意SEO。 通过使用Quasar Meta插件管理搜索引擎所需的动态html标记,可以大大改善SEO。
启动文件
在SSR模式下运行时,您的应用程序代码必须是同构的或“通用的”,这意味着它必须同时在Node上下文和浏览器中运行。 这也适用于您的启动文件 。
但是,在某些情况下,您只希望某些引导文件仅在服务器上或仅在客户端上运行。 您可以通过指定以下内容来实现:
// quasar.config.js
return {
// ...
boot: [
'some-boot-file', // 在服务器和客户端上运行
{ path: 'some-other', server: false } // 此启动文件仅嵌入在客户端
{ path: 'third', client: false } // 该启动文件仅嵌入在服务器端
]
}
不过,只需确保您的应用程序是一致的。
当引导文件在服务器上运行时,您将可以访问默认导出功能上的另一个参数(称为ssrContext):
// 一些启动文件
export default ({ app, ..., ssrContext }) => {
// 您可以将属性添加到ssrContext中,然后在/index.html中使用它们。
// 示例-假设我们ssrContext.someProp ='some value',那么在index模板中我们可以引用它:
// {{ someProp }}
}
当您在/index.html
中添加此类引用(上例中用括号括起来的someProp
)时,请确保告诉Quasar它仅对SSR构建有效:
<!-- /index.html -->
<% if (ctx.mode.ssr) { %>{{ someProp }} <% } %>