Skip to content

Commit 7a78046

Browse files
committed
feat(app-vite): prepare Pinia as soon as possible; stores will be available for use in boot files and even in router initialization #12793
1 parent 0c40f2e commit 7a78046

File tree

9 files changed

+71
-63
lines changed

9 files changed

+71
-63
lines changed

app-vite/bin/quasar-new

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const fse = require('fs-extra')
6464

6565
const { log, warn } = require('../lib/helpers/logger')
6666
const appPaths = require('../lib/app-paths')
67-
const getStoreProvider = require('../lib/helpers/get-store-provider')
67+
const storeProvider = require('../lib/helpers/store-provider')
6868
const defaultFilePath = 'default'
6969

7070
console.log()
@@ -117,8 +117,6 @@ if (type.length === 1) {
117117
type = fullCmd[type]
118118
}
119119

120-
const storeProvider = getStoreProvider()
121-
122120
function getPaths (asset, names) {
123121
return names.map(name => {
124122
const hasExtension = !asset.ext || (asset.ext && name.endsWith(asset.ext))

app-vite/lib/entry-files-generator.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class EntryFilesGenerator {
2323
if (ctx.mode.ssr) {
2424
filePaths.push(
2525
'server-entry.js',
26-
'ssr-pwa.js',
2726
'ssr-middlewares.js',
2827
`ssr-${ctx.dev ? 'dev' : 'prod'}-webserver.js`
2928
)

app-vite/lib/helpers/get-store-provider.js renamed to app-vite/lib/helpers/store-provider.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const getPackageJson = require('./get-package-json')
22
const nodePackager = require('./node-packager')
33

4-
module.exports = function getStoreProvider() {
4+
function getStoreProvider () {
55
/** @type {'pinia' | 'vuex'} */
66
const name = getPackageJson('vuex') !== void 0 ? 'vuex' : 'pinia'
77

@@ -15,3 +15,5 @@ module.exports = function getStoreProvider() {
1515
}
1616
}
1717
}
18+
19+
module.exports = getStoreProvider()

app-vite/lib/quasar-config-file.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const appFilesValidations = require('./helpers/app-files-validations')
1212
const cssVariables = require('./helpers/css-variables')
1313
const getPackageMajorVersion = require('./helpers/get-package-major-version')
1414
const resolveExtension = require('./helpers/resolve-extension')
15-
const getStoreProvider = require('./helpers/get-store-provider')
15+
const storeProvider = require('./helpers/store-provider')
1616

1717
const urlRegex = /^http(s)?:\/\//i
1818
const { findClosestOpenPort } = require('../lib/helpers/net')
@@ -402,7 +402,8 @@ class QuasarConfFile {
402402

403403
Object.assign(cfg.metaConf, {
404404
hasLoadingBarPlugin: cfg.framework.plugins.includes('LoadingBar'),
405-
hasMetaPlugin: cfg.framework.plugins.includes('Meta')
405+
hasMetaPlugin: cfg.framework.plugins.includes('Meta'),
406+
storePackage: storeProvider.name
406407
})
407408

408409
cfg.build = merge({
@@ -476,8 +477,6 @@ class QuasarConfFile {
476477
? cfg.build.vueRouterBase
477478
: formatRouterBase(cfg.build.publicPath)
478479

479-
const storeProvider = getStoreProvider()
480-
481480
// when adding new props here be sure to update
482481
// all impacted devserver diffs (look for this.registerDiff() calls)
483482
cfg.sourceFiles = merge({

app-vite/templates/entry/app.js

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,12 @@ const RootComponent = defineComponent({
6464
})
6565
<% } %>
6666

67-
export default async function (createAppFn, quasarUserOptions<%= ctx.mode.ssr ? ', ssrContext' : '' %>) {
68-
// create store and router instances
69-
<% if (store) { %>
70-
const store = typeof createStore === 'function'
71-
? await createStore({<%= ctx.mode.ssr ? 'ssrContext' : '' %>})
72-
: createStore
73-
74-
// obtain Vuex injection key in case we use TypeScript, not used for Pinia
75-
const { storeKey } = await import('app/<%= sourceFiles.store %>');
76-
<% } %>
77-
const router = typeof createRouter === 'function'
78-
? await createRouter({<%= ctx.mode.ssr ? 'ssrContext' + (store ? ',' : '') : '' %><%= store ? 'store' : '' %>})
79-
: createRouter
80-
<% if (store) { %>
81-
// make router instance available in store
82-
store.$router = router
83-
<% } %>
67+
<% if (ctx.mode.ssr && ctx.mode.pwa) { %>
68+
export const ssrIsRunningOnClientPWA = typeof window !== 'undefined' &&
69+
document.body.getAttribute('data-server-rendered') === null
70+
<% } %>
8471

72+
export default async function (createAppFn, quasarUserOptions<%= ctx.mode.ssr ? ', ssrContext' : '' %>) {
8573
// Create the app instance.
8674
// Here we inject into it the Quasar UI, the router & possibly the store.
8775
const app = createAppFn(RootComponent)
@@ -96,12 +84,49 @@ export default async function (createAppFn, quasarUserOptions<%= ctx.mode.ssr ?
9684
app.config.globalProperties.$q.capacitor = window.Capacitor
9785
<% } %>
9886

87+
// create store and router instances
88+
<% if (store) { %>
89+
const store = typeof createStore === 'function'
90+
? await createStore({<%= ctx.mode.ssr ? 'ssrContext' : '' %>})
91+
: createStore
92+
93+
<% if (metaConf.storePackage === 'vuex') { %>
94+
// obtain Vuex injection key in case we use TypeScript
95+
const { storeKey } = await import('app/<%= sourceFiles.store %>');
96+
<% } else if (metaConf.storePackage === 'pinia') { %>
97+
app.use(store)
98+
99+
<% if (ctx.mode.ssr && ssr.manualStoreHydration !== true) { %>
100+
// prime the store with server-initialized state.
101+
// the state is determined during SSR and inlined in the page markup.
102+
if (typeof window !== 'undefined' && <% if (ctx.mode.pwa) { %>ssrIsRunningOnClientPWA !== true && <% } %>window.__INITIAL_STATE__ !== void 0) {
103+
store.state.value = window.__INITIAL_STATE__
104+
// for security reasons, we'll delete this
105+
delete window.__INITIAL_STATE__
106+
}
107+
<% } %>
108+
<% } %>
109+
<% } %>
110+
111+
const router = typeof createRouter === 'function'
112+
? await createRouter({<%= ctx.mode.ssr ? 'ssrContext' + (store ? ',' : '') : '' %><%= store ? 'store' : '' %>})
113+
: createRouter
114+
115+
<% if (store) { %>
116+
// make router instance available in store
117+
<% if (metaConf.storePackage === 'vuex') { %>
118+
store.$router = router
119+
<% } else if (metaConf.storePackage === 'pinia') { %>
120+
store.use(() => ({ router }))
121+
<% } %>
122+
<% } %>
123+
99124
// Expose the app, the router and the store.
100125
// Note that we are not mounting the app here, since bootstrapping will be
101126
// different depending on whether we are in a browser or on the server.
102127
return {
103128
app,
104-
<%= store ? 'store, storeKey,' : '' %>
129+
<%= store ? 'store,' + (metaConf.storePackage === 'vuex' ? ' storeKey,' : '') : '' %>
105130
router
106131
}
107132
}

app-vite/templates/entry/client-entry.js

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
<% if (ctx.mode.ssr && ctx.mode.pwa) { %>
1515
import { createSSRApp, createApp } from 'vue'
16-
import { isRunningOnPWA } from './ssr-pwa'
1716
<% } else { %>
1817
import { <%= ctx.mode.ssr ? 'createSSRApp' : 'createApp' %> } from 'vue'
1918
<% } %>
@@ -45,7 +44,7 @@ import 'quasar/src/css/flex-addon.<%= metaConf.css.quasarSrcExt %>'
4544
import '<%= asset.path %>'
4645
<% }) %>
4746

48-
import createQuasarApp from './app.js'
47+
import createQuasarApp<% if (ctx.mode.ssr && ctx.mode.pwa) { %>, { ssrIsRunningOnClientPWA }<% } %> from './app.js'
4948
import quasarUserOptions from './quasar-user-options.js'
5049

5150
<% if (ctx.mode.pwa) { %>
@@ -71,20 +70,16 @@ if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream && window.n
7170

7271
const publicPath = `<%= build.publicPath %>`
7372

74-
async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%= bootEntries.length > 0 ? ', bootFiles' : '' %>) {
75-
<% if (ctx.mode.ssr && store && ssr.manualStoreHydration !== true) { %>
73+
async function start ({
74+
app,
75+
router
76+
<%= store ? ', store' + (metaConf.storePackage === 'vuex' ? ', storeKey' : '') : '' %>
77+
}<%= bootEntries.length > 0 ? ', bootFiles' : '' %>) {
78+
<% if (ctx.mode.ssr && store && metaConf.storePackage === 'vuex' && ssr.manualStoreHydration !== true) { %>
7679
// prime the store with server-initialized state.
7780
// the state is determined during SSR and inlined in the page markup.
78-
if (<% if (ctx.mode.pwa) { %>isRunningOnPWA !== true && <% } %>window.__INITIAL_STATE__ !== void 0) {
79-
if (typeof store.replaceState === 'function') {
80-
// it means it's Vuex
81-
store.replaceState(window.__INITIAL_STATE__)
82-
}
83-
else {
84-
// it means it's Pinia
85-
store.state.value = window.__INITIAL_STATE__
86-
}
87-
81+
if (<%= ctx.mode.pwa ? 'ssrIsRunningOnClientPWA !== true &&' : '' %>window.__INITIAL_STATE__ !== void 0) {
82+
store.replaceState(window.__INITIAL_STATE__)
8883
// for security reasons, we'll delete this
8984
delete window.__INITIAL_STATE__
9085
}
@@ -148,13 +143,13 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
148143
<% } %>
149144

150145
app.use(router)
151-
<% if (store) { %>app.use(store, storeKey)<% } %>
146+
<% if (store && metaConf.storePackage === 'vuex') { %>app.use(store, storeKey)<% } %>
152147

153148
<% if (ctx.mode.ssr) { %>
154149
<% if (ctx.mode.pwa) { %>
155-
if (isRunningOnPWA === true) {
150+
if (ssrIsRunningOnClientPWA === true) {
156151
<% if (preFetch) { %>
157-
addPreFetchHooks(router<%= store ? ', store' : '' %>)
152+
addPreFetchHooks({ router, ssrIsRunningOnClientPWA<%= store ? ', store' : '' %> })
158153
<% } %>
159154
app.mount('#q-app')
160155
}
@@ -164,7 +159,7 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
164159
// and async components...
165160
router.isReady().then(() => {
166161
<% if (preFetch) { %>
167-
addPreFetchHooks(router<%= store ? ', store' : '' %>, publicPath)
162+
addPreFetchHooks({ router<%= store ? ', store' : '' %>, publicPath })
168163
<% } %>
169164
app.mount('#q-app')
170165
})
@@ -175,7 +170,7 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
175170
<% } else { // not SSR %>
176171

177172
<% if (preFetch) { %>
178-
addPreFetchHooks(router<%= store ? ', store' : '' %>)
173+
addPreFetchHooks({ router<%= store ? ', store' : '' %> })
179174
<% } %>
180175

181176
<% if (ctx.mode.cordova) { %>
@@ -262,7 +257,7 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
262257

263258
createQuasarApp(<%=
264259
ctx.mode.ssr
265-
? (ctx.mode.pwa ? 'isRunningOnPWA ? createApp : createSSRApp' : 'createSSRApp')
260+
? (ctx.mode.pwa ? 'ssrIsRunningOnClientPWA ? createApp : createSSRApp' : 'createSSRApp')
266261
: 'createApp'
267262
%>, quasarUserOptions)
268263
<% if (bootEntries.length > 0) { %>

app-vite/templates/entry/client-prefetch.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414
import { LoadingBar } from 'quasar'
1515
<% } %>
1616

17-
<% if (ctx.mode.ssr && ctx.mode.pwa) { %>
18-
import { isRunningOnPWA } from './ssr-pwa'
19-
<% } %>
20-
2117
<% if (!ctx.mode.ssr || ctx.mode.pwa) { %>
2218
import App from 'app/<%= sourceFiles.rootComponent %>'
2319
let appPrefetch = typeof App.preFetch === 'function'
@@ -48,7 +44,7 @@ function getMatchedComponents (to, router) {
4844
}))
4945
}
5046

51-
export function addPreFetchHooks (router<%= store ? ', store' : '' %>, publicPath) {
47+
export function addPreFetchHooks ({ router<%= ctx.mode.ssr && ctx.mode.pwa ? ', ssrIsRunningOnClientPWA' : '' %><%= store ? ', store' : '' %>, publicPath }) {
5248
// Add router hook for handling preFetch.
5349
// Doing it after initial route is resolved so that we don't double-fetch
5450
// the data that we already have. Using router.beforeResolve() so that all
@@ -76,7 +72,7 @@ export function addPreFetchHooks (router<%= store ? ', store' : '' %>, publicPat
7672
.map(m => m.c.__c !== void 0 ? m.c.__c.preFetch : m.c.preFetch)
7773

7874
<% if (!ctx.mode.ssr || ctx.mode.pwa) { %>
79-
if (<%= ctx.mode.ssr && ctx.mode.pwa ? 'isRunningOnPWA === true && ' : '' %>appPrefetch !== false) {
75+
if (<%= ctx.mode.ssr && ctx.mode.pwa ? 'ssrIsRunningOnClientPWA === true && ' : '' %>appPrefetch !== false) {
8076
preFetchList.unshift(appPrefetch)
8177
appPrefetch = false
8278
}

app-vite/templates/entry/server-entry.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ export default ssrContext => {
8888
const bootFunctions = await bootFiles
8989
<% } %>
9090

91-
const { app, router<%= store ? ', store, storeKey' : '' %> } = await createQuasarApp(createApp, qUserOptions, ssrContext)
91+
const {
92+
app, router<%= store ? ', store' + (metaConf.storePackage === 'vuex' ? ', storeKey' : '') : '' %>
93+
} = await createQuasarApp(createApp, qUserOptions, ssrContext)
9294

9395
<% if (bootEntries.length !== 0) { %>
9496
let hasRedirected = false
@@ -121,7 +123,7 @@ export default ssrContext => {
121123
<% } %>
122124

123125
app.use(router)
124-
<% if (store) { %>app.use(store, storeKey)<% } %>
126+
<% if (store && metaConf.storePackage === 'vuex') { %>app.use(store, storeKey)<% } %>
125127

126128
const url = ssrContext.req.url<% if (build.publicPath !== '/') { %>.replace(publicPath, '/')<% } %>
127129
const { fullPath } = router.resolve(url)

app-vite/templates/entry/ssr-pwa.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)