quasar.config 文件
这是你可以配置一些 SSR 选项的地方。例如,如果你希望客户端作为 SPA(单页应用程序 - 默认行为)或作为 PWA(渐进式 Web 应用程序)接管。
return {
// ...
ssr: {
pwa: true/false, // should a PWA take over (default: false), or just a SPA?
/**
* Manually serialize the store state and provide it yourself
* as window.__INITIAL_STATE__ to the client-side (through a <script> tag)
* (Requires @quasar/app-webpack v3.5+)
*/
manualStoreSerialization: false,
/**
* Manually inject the store state into ssrContext.state
* (Requires @quasar/app-webpack v3.5+)
*/
manualStoreSsrContextInjection: false,
/**
* Manually handle the store hydration instead of letting Quasar CLI do it.
* For Pinia: store.state.value = window.__INITIAL_STATE__
* For Vuex: store.replaceState(window.__INITIAL_STATE__)
*/
manualStoreHydration: false,
/**
* Manually call $q.onSSRHydrated() instead of letting Quasar CLI do it.
* This announces that client-side code should takeover.
*/
manualPostHydrationTrigger: false,
prodPort: 3000, // The default port that the production server should use
// (gets superseded if process∙env∙PORT is specified at runtime)
maxAge: 1000 * 60 * 60 * 24 * 30,
// Tell browser when a file from the server should expire from cache
// (the default value, in ms)
// Has effect only when server.static() is used
// List of SSR middleware files (src-ssr/middlewares/*). Order is important.
middlewares: [
// ...
'render' // Should not be missing, and should be last in the list.
],
// optional; add/remove/change properties
// of production generated package.json
extendPackageJson (pkg) {
// directly change props of pkg;
// no need to return anything
},
// optional;
// handles the Webserver webpack config ONLY
// which includes the SSR middleware
extendWebpackWebserver (cfg) {
// directly change props of cfg;
// no need to return anything
},
// optional; EQUIVALENT to extendWebpack() but uses webpack-chain;
// handles the Webserver webpack config ONLY
// which includes the SSR middleware
chainWebpackWebserver (chain) {
// chain is a webpack-chain instance
// of the Webpack configuration
}
}
}
如果你决定使用 PWA 客户端接管(**这是一个杀手级的组合**),Quasar CLI PWA 模式也会被安装。你可能想查看 Quasar PWA 指南。但最重要的是,确保你阅读了 SSR 与 PWA 页面。
构建时,extendWebpack()
和 chainWebpack()
将会收到一个额外的参数(Object),当前包含 isServer
或 isClient
布尔值属性,因为将会有两个 Webpack 构建(一个用于服务器端,一个用于客户端)。
build: {
extendWebpack(cfg, { isServer, isClient }) { ... }
}
如果你想要更多信息,请查看此页面,它详细介绍了在 /quasar.config
文件中 处理 Webpack 的更多细节。
手动触发商店水合
默认情况下,Quasar CLI 会在客户端处理 Vuex 商店(如果您使用它)的水合。
但是,如果您希望手动进行水合,您需要在 quasar.config 文件 > ssr > manualStoreHydration: true 中进行设置。一个很好的例子是从 启动文件 中执行。
// MAKE SURE TO CONFIGURE THIS BOOT FILE
// TO RUN ONLY ON CLIENT-SIDE
export default ({ store }) => {
// For Pinia
store.state.value = window.__INITIAL_STATE__
// For Vuex
store.replaceState(window.__INITIAL_STATE__)
}
手动触发后水合
默认情况下,Quasar CLI 会包装您的 App 组件,并在客户端组件挂载时调用 $q.onSSRHydrated()
。这是客户端接管的时刻。您无需为此进行任何配置。
但是,如果您希望覆盖此事件发生的时刻,您需要在 quasar.config 文件 > ssr > manualPostHydrationTrigger: true 中进行设置。无论出于何种原因(非常自定义的用例),这是一个手动触发后水合的示例。
// App.vue
import { onMounted } from 'vue'
import { useQuasar } from 'quasar'
export default {
// ....
setup () {
// ...
const $q = useQuasar()
onMounted(() => {
$q.onSSRHydrated()
})
}
}
Nodejs 服务器
向 Quasar 项目添加 SSR 模式意味着将创建一个新文件夹:/src-ssr
,其中包含 SSR 特定文件
您可以随意编辑这些文件。这两个文件夹中的每一个都详细说明了各自的文档页面(查看左侧菜单)。
注意一些事项
如果您从 node_modules 中导入任何内容,请确保该包在 package.json > “dependencies” 中指定,而不是在 “devDependencies” 中。
The
/src-ssr/middlewares
是通过单独的 Webpack 配置构建的。**当 Quasar App CLI 构建您的应用程序时,您会看到它标记为“Webserver”。**您可以通过/quasar.config
文件来链接/扩展这些文件的 Webpack 配置。
return {
// ...
ssr: {
// ...
// optional; webpack config Object for
// the Webserver part ONLY (/src-ssr/)
// which is invoked for production (NOT for dev)
extendWebpackWebserver (cfg) {
// directly change props of cfg;
// no need to return anything
},
// optional; EQUIVALENT to extendWebpack() but uses webpack-chain;
// the Webserver part ONLY (/src-ssr/)
// which is invoked for production (NOT for dev)
chainWebpackWebserver (chain) {
// chain is a webpack-chain instance
// of the Webpack configuration
}
}
}
- The
/src-ssr/production-export.js
文件在 SSR 生产导出 页面中有详细说明。如果您需要支持无服务器函数,请阅读它。
帮助 SEO
开发 SSR 而不是 SPA 的主要原因之一是为了处理 SEO。使用 Quasar Meta 插件 来管理搜索引擎所需的动态 html 标记,可以极大地提高 SEO。
启动文件
在 SSR 模式下运行时,您的应用程序代码需要是同构的或“通用的”,这意味着它必须在 Node 上下文和浏览器中运行。这也适用于您的 启动文件。
但是,有些情况下您只想让某些启动文件仅在服务器上运行,或者仅在客户端运行。您可以通过指定以下内容来实现。
return {
// ...
boot: [
'some-boot-file', // runs on both server and client
{ path: 'some-other', server: false }, // this boot file gets embedded only on client-side
{ path: 'third', client: false } // this boot file gets embedded only on server-side
]
}
不过,请确保您的应用程序保持一致。
当启动文件在服务器上运行时,您将在默认导出的函数中访问一个额外的参数(称为 ssrContext)。
export default ({ app, ..., ssrContext }) => {
// You can add props to the ssrContext then use them in the src/index.template.html.
// Example - let's say we ssrContext.someProp = 'some value', then in index template we can reference it:
// {{ someProp }}
}
当您将此类引用(someProp
在上面的示例中用括号括起来)添加到 /index.html 或 /src/index.template.html 时,请确保告知 Quasar 它仅对 SSR 构建有效。
<% if (ctx.mode.ssr) { %>{{ someProp }} <% } %>