Skip to content

Commit fa72f6a

Browse files
committed
feat(app-webpack): prepare Pinia as soon as possible; stores will be available for use in boot files and even in router initialization quasarframework#12793
1 parent a94f9d9 commit fa72f6a

File tree

11 files changed

+81
-73
lines changed

11 files changed

+81
-73
lines changed

app-vite/templates/entry/app.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,14 @@ export default async function (createAppFn, quasarUserOptions<%= ctx.mode.ssr ?
8484
app.config.globalProperties.$q.capacitor = window.Capacitor
8585
<% } %>
8686

87-
// create store and router instances
8887
<% if (store) { %>
8988
const store = typeof createStore === 'function'
9089
? await createStore({<%= ctx.mode.ssr ? 'ssrContext' : '' %>})
9190
: createStore
9291

9392
<% if (metaConf.storePackage === 'vuex') { %>
9493
// obtain Vuex injection key in case we use TypeScript
95-
const { storeKey } = await import('app/<%= sourceFiles.store %>');
94+
const { storeKey } = await import('app/<%= sourceFiles.store %>')
9695
<% } else if (metaConf.storePackage === 'pinia') { %>
9796
app.use(store)
9897

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ async function start ({
7676
<%= store ? ', store' + (metaConf.storePackage === 'vuex' ? ', storeKey' : '') : '' %>
7777
}<%= bootEntries.length > 0 ? ', bootFiles' : '' %>) {
7878
<% if (ctx.mode.ssr && store && metaConf.storePackage === 'vuex' && ssr.manualStoreHydration !== true) { %>
79-
// prime the store with server-initialized state.
80-
// the state is determined during SSR and inlined in the page markup.
81-
if (<%= ctx.mode.pwa ? 'ssrIsRunningOnClientPWA !== true &&' : '' %>window.__INITIAL_STATE__ !== void 0) {
82-
store.replaceState(window.__INITIAL_STATE__)
83-
// for security reasons, we'll delete this
84-
delete window.__INITIAL_STATE__
85-
}
79+
// prime the store with server-initialized state.
80+
// the state is determined during SSR and inlined in the page markup.
81+
if (<%= ctx.mode.pwa ? 'ssrIsRunningOnClientPWA !== true &&' : '' %>window.__INITIAL_STATE__ !== void 0) {
82+
store.replaceState(window.__INITIAL_STATE__)
83+
// for security reasons, we'll delete this
84+
delete window.__INITIAL_STATE__
85+
}
8686
<% } %>
8787

8888
<% if (bootEntries.length > 0) { %>

app-webpack/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
if (argv._.length < 2) {
@@ -115,8 +115,6 @@ if (type.length === 1) {
115115
type = fullCmd[type]
116116
}
117117

118-
const storeProvider = getStoreProvider()
119-
120118
function getPaths (asset, names) {
121119
return names.map(name => {
122120
const hasExtension = !asset.ext || (asset.ext && name.endsWith(asset.ext))

app-webpack/lib/generator.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class Generator {
2323
if (ctx.mode.ssr) {
2424
paths.push(
2525
'server-entry.js',
26-
'ssr-pwa.js',
2726
'ssr-middlewares.js'
2827
)
2928

app-webpack/lib/helpers/get-store-provider.js renamed to app-webpack/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-webpack/lib/quasar-conf-file.js

Lines changed: 3 additions & 3 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 getDevlandFile = require('./helpers/get-devland-file')
1414
const getPackageMajorVersion = require('./helpers/get-package-major-version')
15-
const getStoreProvider = require('./helpers/get-store-provider')
15+
const storeProvider = require('./helpers/store-provider')
1616
const { quasarVersion } = require('./helpers/banner')
1717

1818
const transformAssetUrls = getDevlandFile('quasar/dist/transforms/loader-asset-urls.json')
@@ -518,8 +518,6 @@ class QuasarConfFile {
518518
? cfg.build.appBase
519519
: cfg.build.publicPath
520520

521-
const storeProvider = getStoreProvider()
522-
523521
cfg.sourceFiles = merge({
524522
rootComponent: 'src/App.vue',
525523
router: 'src/router/index',
@@ -533,6 +531,8 @@ class QuasarConfFile {
533531

534532
appFilesValidations(cfg)
535533

534+
cfg.__storePackage = storeProvider.name
535+
536536
// do we have a store?
537537
const storePath = appPaths.resolve.app(cfg.sourceFiles.store)
538538
cfg.store = (

app-webpack/templates/entry/app.js

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

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

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

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

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

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
<% if (ctx.mode.ssr && ctx.mode.pwa) { %>
1414
import { createSSRApp, createApp } from 'vue'
15-
import { isRunningOnPWA } from './ssr-pwa'
1615
<% } else { %>
1716
import { <%= ctx.mode.ssr ? 'createSSRApp' : 'createApp' %> } from 'vue'
1817
<% } %>
@@ -44,7 +43,7 @@ import 'quasar/src/css/flex-addon.<%= __css.quasarSrcExt %>'
4443
import '<%= asset.path %>'
4544
<% }) %>
4645

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

5049
<% if (ctx.mode.pwa) { %>
@@ -75,23 +74,19 @@ const doubleSlashRE = /\/\//
7574
const addPublicPath = url => (publicPath + url).replace(doubleSlashRE, '/')
7675
<% } %>
7776

78-
async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%= bootEntries.length > 0 ? ', bootFiles' : '' %>) {
79-
<% if (ctx.mode.ssr && store && ssr.manualStoreHydration !== true) { %>
80-
// prime the store with server-initialized state.
81-
// the state is determined during SSR and inlined in the page markup.
82-
if (<% if (ctx.mode.pwa) { %>isRunningOnPWA !== true && <% } %>window.__INITIAL_STATE__ !== void 0) {
83-
if (typeof store.replaceState === 'function') {
84-
// it means it's Vuex
77+
async function start ({
78+
app,
79+
router
80+
<%= store ? ', store' + (__storePackage === 'vuex' ? ', storeKey' : '') : '' %>
81+
}<%= bootEntries.length > 0 ? ', bootFiles' : '' %>) {
82+
<% if (ctx.mode.ssr && store && __storePackage === 'vuex' && ssr.manualStoreHydration !== true) { %>
83+
// prime the store with server-initialized state.
84+
// the state is determined during SSR and inlined in the page markup.
85+
if (<%= ctx.mode.pwa ? 'ssrIsRunningOnClientPWA !== true &&' : '' %>window.__INITIAL_STATE__ !== void 0) {
8586
store.replaceState(window.__INITIAL_STATE__)
87+
// for security reasons, we'll delete this
88+
delete window.__INITIAL_STATE__
8689
}
87-
else {
88-
// it means it's Pinia
89-
store.state.value = window.__INITIAL_STATE__
90-
}
91-
92-
// for security reasons, we'll delete this
93-
delete window.__INITIAL_STATE__
94-
}
9590
<% } %>
9691

9792
<% if (bootEntries.length > 0) { %>
@@ -152,13 +147,13 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
152147
<% } %>
153148

154149
app.use(router)
155-
<% if (store) { %>app.use(store, storeKey)<% } %>
150+
<% if (store && __storePackage === 'vuex') { %>app.use(store, storeKey)<% } %>
156151

157152
<% if (ctx.mode.ssr) { %>
158153
<% if (ctx.mode.pwa) { %>
159-
if (isRunningOnPWA === true) {
154+
if (ssrIsRunningOnClientPWA === true) {
160155
<% if (preFetch) { %>
161-
addPreFetchHooks(router<%= store ? ', store' : '' %>)
156+
addPreFetchHooks({ router, ssrIsRunningOnClientPWA<%= store ? ', store' : '' %> })
162157
<% } %>
163158
app.mount('#q-app')
164159
}
@@ -168,7 +163,7 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
168163
// and async components...
169164
router.isReady().then(() => {
170165
<% if (preFetch) { %>
171-
addPreFetchHooks(router<%= store ? ', store' : '' %>, publicPath)
166+
addPreFetchHooks({ router<%= store ? ', store' : '' %>, publicPath })
172167
<% } %>
173168
app.mount('#q-app')
174169
})
@@ -179,7 +174,7 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
179174
<% } else { // not SSR %>
180175

181176
<% if (preFetch) { %>
182-
addPreFetchHooks(router<%= store ? ', store' : '' %>)
177+
addPreFetchHooks({ router<%= store ? ', store' : '' %> })
183178
<% } %>
184179

185180
<% if (ctx.mode.cordova) { %>
@@ -266,7 +261,7 @@ async function start ({ app, router<%= store ? ', store, storeKey' : '' %> }<%=
266261

267262
createQuasarApp(<%=
268263
ctx.mode.ssr
269-
? (ctx.mode.pwa ? 'isRunningOnPWA ? createApp : createSSRApp' : 'createSSRApp')
264+
? (ctx.mode.pwa ? 'ssrIsRunningOnClientPWA ? createApp : createSSRApp' : 'createSSRApp')
270265
: 'createApp'
271266
%>, quasarUserOptions)
272267
<% if (bootEntries.length > 0) { %>

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

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

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

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

7773
<% if (!ctx.mode.ssr || ctx.mode.pwa) { %>
78-
if (<%= ctx.mode.ssr && ctx.mode.pwa ? 'isRunningOnPWA === true && ' : '' %>appPrefetch !== false) {
74+
if (<%= ctx.mode.ssr && ctx.mode.pwa ? 'ssrIsRunningOnClientPWA === true && ' : '' %>appPrefetch !== false) {
7975
preFetchList.unshift(appPrefetch)
8076
appPrefetch = false
8177
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ const { components, directives, ...qUserOptions } = quasarUserOptions
8888
// return a Promise that resolves to the app instance.
8989
export default ssrContext => {
9090
return new Promise(async (resolve, reject) => {
91-
const { app, router<%= store ? ', store, storeKey' : '' %> } = await createQuasarApp(createApp, qUserOptions, ssrContext)
91+
const {
92+
app, router<%= store ? ', store' + (__storePackage === 'vuex' ? ', storeKey' : '') : '' %>
93+
} = await createQuasarApp(createApp, qUserOptions, ssrContext)
9294

9395
<% if (bootNames.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 && __storePackage === 'vuex') { %>app.use(store, storeKey)<% } %>
125127

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

0 commit comments

Comments
 (0)