zova-ui-empty 5.0.258 → 5.0.261
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/env/.env.ssr.admin +3 -0
- package/env/.env.ssr.production +5 -0
- package/index.html +15 -8
- package/package.json +18 -7
- package/quasar.config.ts +19 -0
- package/quasar.extensions.json +3 -0
- package/src/boot/main.ts +3 -10
- package/src/boot/zova.ts +6 -0
- package/src/suite/a-home/modules/home-layout/src/component/layoutDefault/controller.ts +6 -1
- package/src-ssr/middlewares/env.ts +21 -0
- package/src-ssr/middlewares/render.ts +60 -0
- package/src-ssr/server.ts +141 -0
- package/src-ssr/ssr-flag.d.ts +10 -0
- package/env/.env.development +0 -0
- package/env/.env.production +0 -0
- package/vite.config.ts +0 -44
package/index.html
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html
|
|
2
|
+
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
<meta
|
|
7
|
-
<
|
|
8
|
-
|
|
4
|
+
<title><%= productName %></title>
|
|
5
|
+
|
|
6
|
+
<meta charset="utf-8" />
|
|
7
|
+
<meta name="description" content="<%= productDescription %>" />
|
|
8
|
+
<meta name="format-detection" content="telephone=no" />
|
|
9
|
+
<meta name="msapplication-tap-highlight" content="no" />
|
|
10
|
+
<meta
|
|
11
|
+
name="viewport"
|
|
12
|
+
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
|
|
13
|
+
/>
|
|
9
14
|
|
|
15
|
+
<link rel="icon" type="image/ico" href="favicon.ico" />
|
|
16
|
+
</head>
|
|
10
17
|
<body>
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
<!-- quasar:entry-point -->
|
|
19
|
+
<!--app-teleports-->
|
|
13
20
|
</body>
|
|
14
21
|
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-ui-empty",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.261",
|
|
4
4
|
"description": "A vue3 empty framework with ioc",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -8,9 +8,17 @@
|
|
|
8
8
|
"author": "zhennann <zhen.nann@icloud.com>",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
|
-
"dev": "
|
|
12
|
-
"build": "
|
|
13
|
-
"preview": "
|
|
11
|
+
"dev": "npm run dev:ssr:admin",
|
|
12
|
+
"build": "npm run build:ssr:admin",
|
|
13
|
+
"preview": "npm run preview:ssr",
|
|
14
|
+
"dev:ssr:admin": "tsc -b && quasar dev --mode ssr --flavor admin",
|
|
15
|
+
"dev:ssr:front": "tsc -b && quasar dev --mode ssr --flavor front",
|
|
16
|
+
"build:ssr:admin": "tsc -b && npm run tsc && quasar build --mode ssr --flavor admin",
|
|
17
|
+
"build:ssr:front": "tsc -b && npm run tsc && quasar build --mode ssr --flavor front",
|
|
18
|
+
"preview:ssr": "concurrently \"cd ./distMockServer && node index.js\" \"node ./dist/ssr/index.js\"",
|
|
19
|
+
"dev:spa": "tsc -b && quasar dev --mode spa --flavor admin",
|
|
20
|
+
"build:spa": "tsc -b && npm run tsc && quasar build --mode spa --flavor admin",
|
|
21
|
+
"preview:spa": "vite preview --outDir=dist/spa",
|
|
14
22
|
"tsc": "vue-tsc --noEmit --project tsconfig.vue-tsc.json",
|
|
15
23
|
"lint": "eslint . --fix --ignore-path .gitignore"
|
|
16
24
|
},
|
|
@@ -35,22 +43,25 @@
|
|
|
35
43
|
"connect": "^3.7.0",
|
|
36
44
|
"cors": "^2.8.5",
|
|
37
45
|
"express": "^4.19.2",
|
|
46
|
+
"quasar": "^2.16.8",
|
|
38
47
|
"typestyle": "^2.4.0",
|
|
39
48
|
"vue": "^3.4.29",
|
|
40
49
|
"vue-router": "^4.3.3",
|
|
41
50
|
"zod": "^3.23.8",
|
|
42
|
-
"zova": "^5.0.
|
|
51
|
+
"zova": "^5.0.190",
|
|
43
52
|
"zova-module-a-model": "^5.0.24",
|
|
44
53
|
"zova-module-a-pinia": "^5.0.24",
|
|
45
54
|
"zova-module-a-router": "^5.0.58",
|
|
46
|
-
"zova-module-a-style": "^5.0.
|
|
55
|
+
"zova-module-a-style": "^5.0.35",
|
|
47
56
|
"zova-module-a-tabs": "^5.0.18"
|
|
48
57
|
},
|
|
49
58
|
"devDependencies": {
|
|
50
59
|
"@cabloy/lint": "^4.0.11",
|
|
60
|
+
"@quasar/app-vite": "2.0.0-beta.18",
|
|
51
61
|
"@types/node": "^20.14.2",
|
|
52
62
|
"@vitejs/plugin-vue": "^5.0.5",
|
|
53
63
|
"concurrently": "^8.2.2",
|
|
64
|
+
"quasar-app-extension-zova": "^1.1.153",
|
|
54
65
|
"sass": "^1.77.5",
|
|
55
66
|
"typescript": "^5.4.5",
|
|
56
67
|
"vite": "^5.3.1",
|
|
@@ -58,5 +69,5 @@
|
|
|
58
69
|
"zova-vite": "^1.0.157"
|
|
59
70
|
},
|
|
60
71
|
"license": "MIT",
|
|
61
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "6634268bdb6e583d44f84a0befd39afb431ce678"
|
|
62
73
|
}
|
package/quasar.config.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-env node */
|
|
2
|
+
|
|
3
|
+
// Configuration for your app
|
|
4
|
+
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js
|
|
5
|
+
|
|
6
|
+
import { configure } from 'quasar/wrappers';
|
|
7
|
+
|
|
8
|
+
export default configure(_ctx => {
|
|
9
|
+
return {
|
|
10
|
+
build: {
|
|
11
|
+
// extendViteConf(_viteConf) {},
|
|
12
|
+
// viteVuePluginOptions: {},
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
devServer: {
|
|
16
|
+
open: false, // opens browser window automatically
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
});
|
package/src/boot/main.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import App from './app/index.vue';
|
|
1
|
+
import { SSRContext } from 'zova';
|
|
2
|
+
import { App } from 'vue';
|
|
4
3
|
|
|
5
4
|
import '../css/settings.scss';
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
app.use(PluginBean);
|
|
9
|
-
app.mount('#app');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const app = createApp(App);
|
|
13
|
-
start({ app });
|
|
6
|
+
export default (_app: App, _ssrContext: SSRContext) => {};
|
package/src/boot/zova.ts
ADDED
|
@@ -16,7 +16,12 @@ export class ControllerLayoutDefault extends BeanControllerBase<unknown, Props,
|
|
|
16
16
|
|
|
17
17
|
leftDrawerOpen: boolean = false;
|
|
18
18
|
|
|
19
|
-
protected async __init__() {
|
|
19
|
+
protected async __init__() {
|
|
20
|
+
// menu
|
|
21
|
+
const queryMenus = this.$$modelMenu.select();
|
|
22
|
+
await queryMenus.suspense();
|
|
23
|
+
if (queryMenus.error) throw queryMenus.error;
|
|
24
|
+
}
|
|
20
25
|
|
|
21
26
|
toggleLeftDrawer() {
|
|
22
27
|
this.leftDrawerOpen = !this.leftDrawerOpen;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import path, { dirname } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { ssrMiddleware } from 'quasar/wrappers';
|
|
5
|
+
|
|
6
|
+
// This middleware should execute as first one
|
|
7
|
+
// since it prepare the process.env variables
|
|
8
|
+
|
|
9
|
+
export default ssrMiddleware(({ app: _app, resolve: _resolve, render: _render, serve: _serve }) => {
|
|
10
|
+
if (process.env.PROD) {
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
const envContent = readFileSync(path.join(__dirname, './.env.json'));
|
|
14
|
+
const env = JSON.parse(envContent.toString());
|
|
15
|
+
for (const key of Object.keys(env)) {
|
|
16
|
+
if (process.env[key] === undefined && env[key] !== false) {
|
|
17
|
+
process.env[key] = env[key];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
import { RenderError } from '@quasar/app-vite';
|
|
3
|
+
import { ssrMiddleware } from 'quasar/wrappers';
|
|
4
|
+
|
|
5
|
+
// This middleware should execute as last one
|
|
6
|
+
// since it captures everything and tries to
|
|
7
|
+
// render the page with Vue
|
|
8
|
+
|
|
9
|
+
export default ssrMiddleware(({ app, resolve, render, serve }) => {
|
|
10
|
+
// we capture any other Express route and hand it
|
|
11
|
+
// over to Vue and Vue Router to render our page
|
|
12
|
+
app.get(resolve.urlPath('*'), (req: Request, res: Response) => {
|
|
13
|
+
res.setHeader('Content-Type', 'text/html');
|
|
14
|
+
|
|
15
|
+
render(/* the ssrContext: */ { req, res })
|
|
16
|
+
.then((html) => {
|
|
17
|
+
// now let's send the rendered html to the client
|
|
18
|
+
res.send(html);
|
|
19
|
+
})
|
|
20
|
+
.catch((err: RenderError) => {
|
|
21
|
+
// oops, we had an error while rendering the page
|
|
22
|
+
|
|
23
|
+
// we were told to redirect to another URL
|
|
24
|
+
if (err.url) {
|
|
25
|
+
if (err.code) {
|
|
26
|
+
res.redirect(err.code, err.url);
|
|
27
|
+
} else {
|
|
28
|
+
res.redirect(err.url);
|
|
29
|
+
}
|
|
30
|
+
} else if (err.code === 404) {
|
|
31
|
+
// hmm, Vue Router could not find the requested route
|
|
32
|
+
|
|
33
|
+
// Should reach here only if no "catch-all" route
|
|
34
|
+
// is defined in /src/routes
|
|
35
|
+
res.status(404).send('404 | Page Not Found');
|
|
36
|
+
} else if (process.env.DEV) {
|
|
37
|
+
// well, we treat any other code as error;
|
|
38
|
+
// if we're in dev mode, then we can use Quasar CLI
|
|
39
|
+
// to display a nice error page that contains the stack
|
|
40
|
+
// and other useful information
|
|
41
|
+
|
|
42
|
+
// serve.error is available on dev only
|
|
43
|
+
serve.error({ err, req, res });
|
|
44
|
+
} else {
|
|
45
|
+
// we're in production, so we should have another method
|
|
46
|
+
// to display something to the client when we encounter an error
|
|
47
|
+
// (for security reasons, it's not ok to display the same wealth
|
|
48
|
+
// of information as we do in development)
|
|
49
|
+
|
|
50
|
+
// Render Error Page on production or
|
|
51
|
+
// create a route (/src/routes) for an error page and redirect to it
|
|
52
|
+
res.status(500).send('500 | Internal Server Error');
|
|
53
|
+
|
|
54
|
+
if (process.env.DEBUGGING) {
|
|
55
|
+
console.error(err.stack);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* More info about this file:
|
|
3
|
+
* https://v2.quasar.dev/quasar-cli-vite/developing-ssr/ssr-webserver
|
|
4
|
+
*
|
|
5
|
+
* Runs in Node context.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Make sure to yarn add / npm install (in your project root)
|
|
10
|
+
* anything you import here (except for express and compression).
|
|
11
|
+
*/
|
|
12
|
+
import express from 'express';
|
|
13
|
+
import compression from 'compression';
|
|
14
|
+
import {
|
|
15
|
+
ssrClose,
|
|
16
|
+
ssrCreate,
|
|
17
|
+
ssrListen,
|
|
18
|
+
ssrServeStaticContent,
|
|
19
|
+
ssrRenderPreloadTag,
|
|
20
|
+
} from 'quasar/wrappers';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Create your webserver and return its instance.
|
|
24
|
+
* If needed, prepare your webserver to receive
|
|
25
|
+
* connect-like middlewares.
|
|
26
|
+
*
|
|
27
|
+
* Can be async: ssrCreate(async ({ ... }) => { ... })
|
|
28
|
+
*/
|
|
29
|
+
export const create = ssrCreate((/* { ... } */) => {
|
|
30
|
+
const app = express();
|
|
31
|
+
|
|
32
|
+
// attackers can use this header to detect apps running Express
|
|
33
|
+
// and then launch specifically-targeted attacks
|
|
34
|
+
app.disable('x-powered-by');
|
|
35
|
+
|
|
36
|
+
// place here any middlewares that
|
|
37
|
+
// absolutely need to run before anything else
|
|
38
|
+
if (process.env.PROD) {
|
|
39
|
+
app.use(compression());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return app;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* You need to make the server listen to the indicated port
|
|
47
|
+
* and return the listening instance or whatever you need to
|
|
48
|
+
* close the server with.
|
|
49
|
+
*
|
|
50
|
+
* The "listenResult" param for the "close()" definition below
|
|
51
|
+
* is what you return here.
|
|
52
|
+
*
|
|
53
|
+
* For production, you can instead export your
|
|
54
|
+
* handler for serverless use or whatever else fits your needs.
|
|
55
|
+
*
|
|
56
|
+
* Can be async: ssrListen(async ({ app, devHttpsApp, port }) => { ... })
|
|
57
|
+
*/
|
|
58
|
+
export const listen = ssrListen(({ app, devHttpsApp, port }) => {
|
|
59
|
+
const server = devHttpsApp || app;
|
|
60
|
+
return server.listen(port, () => {
|
|
61
|
+
if (process.env.PROD) {
|
|
62
|
+
console.log('Server listening at port ' + port);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Should close the server and free up any resources.
|
|
69
|
+
* Will be used on development only when the server needs
|
|
70
|
+
* to be rebooted.
|
|
71
|
+
*
|
|
72
|
+
* Should you need the result of the "listen()" call above,
|
|
73
|
+
* you can use the "listenResult" param.
|
|
74
|
+
*
|
|
75
|
+
* Can be async: ssrClose(async ({ listenResult }) => { ... }))
|
|
76
|
+
*/
|
|
77
|
+
export const close = ssrClose(({ listenResult }) => {
|
|
78
|
+
return listenResult.close();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const maxAge = process.env.DEV ? 0 : 1000 * 60 * 60 * 24 * 30;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Should return a function that will be used to configure the webserver
|
|
85
|
+
* to serve static content at "urlPath" from "pathToServe" folder/file.
|
|
86
|
+
*
|
|
87
|
+
* Notice resolve.urlPath(urlPath) and resolve.public(pathToServe) usages.
|
|
88
|
+
*
|
|
89
|
+
* Can be async: ssrServeStaticContent(async ({ app, resolve }) => {
|
|
90
|
+
* Can return an async function: return async ({ urlPath = '/', pathToServe = '.', opts = {} }) => {
|
|
91
|
+
*/
|
|
92
|
+
export const serveStaticContent = ssrServeStaticContent(({ app, resolve }) => {
|
|
93
|
+
return ({ urlPath = '/', pathToServe = '.', opts = {} }) => {
|
|
94
|
+
const serveFn = express.static(resolve.public(pathToServe), { maxAge, ...opts });
|
|
95
|
+
app.use(resolve.urlPath(urlPath), serveFn);
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const jsRE = /\.js$/;
|
|
100
|
+
const cssRE = /\.css$/;
|
|
101
|
+
const woffRE = /\.woff$/;
|
|
102
|
+
const woff2RE = /\.woff2$/;
|
|
103
|
+
const gifRE = /\.gif$/;
|
|
104
|
+
const jpgRE = /\.jpe?g$/;
|
|
105
|
+
const pngRE = /\.png$/;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Should return a String with HTML output
|
|
109
|
+
* (if any) for preloading indicated file
|
|
110
|
+
*/
|
|
111
|
+
export const renderPreloadTag = ssrRenderPreloadTag((file/* , { ssrContext } */) => {
|
|
112
|
+
if (jsRE.test(file) === true) {
|
|
113
|
+
return `<link rel="modulepreload" href="${file}" crossorigin>`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (cssRE.test(file) === true) {
|
|
117
|
+
return `<link rel="stylesheet" href="${file}" crossorigin>`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (woffRE.test(file) === true) {
|
|
121
|
+
return `<link rel="preload" href="${file}" as="font" type="font/woff" crossorigin>`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (woff2RE.test(file) === true) {
|
|
125
|
+
return `<link rel="preload" href="${file}" as="font" type="font/woff2" crossorigin>`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (gifRE.test(file) === true) {
|
|
129
|
+
return `<link rel="preload" href="${file}" as="image" type="image/gif" crossorigin>`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (jpgRE.test(file) === true) {
|
|
133
|
+
return `<link rel="preload" href="${file}" as="image" type="image/jpeg" crossorigin>`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (pngRE.test(file) === true) {
|
|
137
|
+
return `<link rel="preload" href="${file}" as="image" type="image/png" crossorigin>`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return '';
|
|
141
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
|
|
3
|
+
// REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
|
|
4
|
+
import "quasar/dist/types/feature-flag";
|
|
5
|
+
|
|
6
|
+
declare module "quasar/dist/types/feature-flag" {
|
|
7
|
+
interface QuasarFeatureFlags {
|
|
8
|
+
ssr: true;
|
|
9
|
+
}
|
|
10
|
+
}
|
package/env/.env.development
DELETED
|
File without changes
|
package/env/.env.production
DELETED
|
File without changes
|
package/vite.config.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// Plugins
|
|
2
|
-
import Vue from '@vitejs/plugin-vue';
|
|
3
|
-
|
|
4
|
-
// Utilities
|
|
5
|
-
import { defineConfig, mergeConfig } from 'vite';
|
|
6
|
-
import { getAppMode, getFlavor } from 'zova-vite';
|
|
7
|
-
import { ZovaConfigMeta } from 'zova';
|
|
8
|
-
import { generateZovaViteMeta } from 'zova-vite';
|
|
9
|
-
|
|
10
|
-
// https://vitejs.dev/config/
|
|
11
|
-
export default defineConfig(async ({ mode }) => {
|
|
12
|
-
const flavor = getFlavor();
|
|
13
|
-
const appMode = getAppMode();
|
|
14
|
-
const configMeta: ZovaConfigMeta = {
|
|
15
|
-
flavor,
|
|
16
|
-
mode,
|
|
17
|
-
appMode,
|
|
18
|
-
};
|
|
19
|
-
const configOptions = {
|
|
20
|
-
appDir: process.cwd(),
|
|
21
|
-
runtimeDir: '.zova',
|
|
22
|
-
zovaManualChunk: {
|
|
23
|
-
debug: false,
|
|
24
|
-
vendors: [],
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
// zovaViteMeta
|
|
28
|
-
const zovaViteMeta = await generateZovaViteMeta(configMeta, configOptions);
|
|
29
|
-
// plugins
|
|
30
|
-
const plugins = [Vue({})];
|
|
31
|
-
for (const plugin of zovaViteMeta.vitePlugins) {
|
|
32
|
-
const pluginFn = plugin[1];
|
|
33
|
-
const pluginOptions = plugin[2];
|
|
34
|
-
plugins.push(pluginFn(pluginOptions));
|
|
35
|
-
}
|
|
36
|
-
// viteConfig
|
|
37
|
-
const viteConfig = mergeConfig(zovaViteMeta.viteConfig, {
|
|
38
|
-
plugins,
|
|
39
|
-
build: {
|
|
40
|
-
// minify: false,
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
return viteConfig;
|
|
44
|
-
});
|