create-vite-extra 2.0.2 → 2.1.1
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/README.md +33 -31
- package/index.js +47 -6
- package/package.json +1 -1
- package/template-ssr-preact/server.js +1 -1
- package/template-ssr-preact-ts/server.js +1 -1
- package/template-ssr-react/server.js +1 -1
- package/template-ssr-react-ts/server.js +1 -1
- package/template-ssr-solid/server.js +1 -1
- package/template-ssr-solid-ts/server.js +1 -1
- package/template-ssr-svelte/server.js +1 -1
- package/template-ssr-svelte-ts/server.js +1 -1
- package/template-ssr-vanilla/server.js +1 -1
- package/template-ssr-vanilla-ts/server.js +1 -1
- package/template-ssr-vue/server.js +1 -1
- package/template-ssr-vue-streaming/README.md +7 -0
- package/template-ssr-vue-streaming/_gitignore +24 -0
- package/template-ssr-vue-streaming/index.html +14 -0
- package/template-ssr-vue-streaming/package.json +24 -0
- package/template-ssr-vue-streaming/public/vite.svg +1 -0
- package/template-ssr-vue-streaming/server.js +77 -0
- package/template-ssr-vue-streaming/src/App.vue +31 -0
- package/template-ssr-vue-streaming/src/assets/vue.svg +1 -0
- package/template-ssr-vue-streaming/src/components/HelloWorld.vue +40 -0
- package/template-ssr-vue-streaming/src/entry-client.js +6 -0
- package/template-ssr-vue-streaming/src/entry-server.js +15 -0
- package/template-ssr-vue-streaming/src/main.js +10 -0
- package/template-ssr-vue-streaming/src/style.css +79 -0
- package/template-ssr-vue-streaming/vite.config.js +7 -0
- package/template-ssr-vue-streaming-ts/README.md +16 -0
- package/template-ssr-vue-streaming-ts/_gitignore +24 -0
- package/template-ssr-vue-streaming-ts/index.html +14 -0
- package/template-ssr-vue-streaming-ts/package.json +28 -0
- package/template-ssr-vue-streaming-ts/public/vite.svg +1 -0
- package/template-ssr-vue-streaming-ts/server.js +77 -0
- package/template-ssr-vue-streaming-ts/src/App.vue +31 -0
- package/template-ssr-vue-streaming-ts/src/assets/vue.svg +1 -0
- package/template-ssr-vue-streaming-ts/src/components/HelloWorld.vue +38 -0
- package/template-ssr-vue-streaming-ts/src/entry-client.ts +6 -0
- package/template-ssr-vue-streaming-ts/src/entry-server.ts +15 -0
- package/template-ssr-vue-streaming-ts/src/main.ts +10 -0
- package/template-ssr-vue-streaming-ts/src/style.css +79 -0
- package/template-ssr-vue-streaming-ts/src/vite-env.d.ts +7 -0
- package/template-ssr-vue-streaming-ts/tsconfig.json +25 -0
- package/template-ssr-vue-streaming-ts/tsconfig.node.json +10 -0
- package/template-ssr-vue-streaming-ts/vite.config.ts +7 -0
- package/template-ssr-vue-ts/server.js +1 -1
package/README.md
CHANGED
|
@@ -58,37 +58,39 @@ bunx create-vite my-vue-app --template ssr-vue
|
|
|
58
58
|
|
|
59
59
|
Currently supported template presets include:
|
|
60
60
|
|
|
61
|
-
| Template
|
|
62
|
-
|
|
|
63
|
-
| `ssr-vanilla`
|
|
64
|
-
| `ssr-vanilla-ts`
|
|
65
|
-
| `ssr-vue`
|
|
66
|
-
| `ssr-vue-ts`
|
|
67
|
-
| `ssr-
|
|
68
|
-
| `ssr-
|
|
69
|
-
| `ssr-react
|
|
70
|
-
| `ssr-react-
|
|
71
|
-
| `ssr-
|
|
72
|
-
| `ssr-
|
|
73
|
-
| `ssr-
|
|
74
|
-
| `ssr-
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `deno-
|
|
78
|
-
| `deno-
|
|
79
|
-
| `deno-
|
|
80
|
-
| `deno-
|
|
81
|
-
| `deno-react
|
|
82
|
-
| `deno-react-
|
|
83
|
-
| `deno-
|
|
84
|
-
| `deno-
|
|
85
|
-
| `deno-
|
|
86
|
-
| `deno-
|
|
87
|
-
| `deno-
|
|
88
|
-
| `deno-
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
61
|
+
| Template | Try online |
|
|
62
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
63
|
+
| `ssr-vanilla` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-vanilla) |
|
|
64
|
+
| `ssr-vanilla-ts` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-vanilla-ts) |
|
|
65
|
+
| `ssr-vue` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-vue) |
|
|
66
|
+
| `ssr-vue-ts` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-vue-ts) |
|
|
67
|
+
| `ssr-vue-streaming` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-vue-streaming) |
|
|
68
|
+
| `ssr-vue-streaming-ts` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-vue-streaming-ts) |
|
|
69
|
+
| `ssr-react` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-react) |
|
|
70
|
+
| `ssr-react-ts` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-react-ts) |
|
|
71
|
+
| `ssr-react-swc` | |
|
|
72
|
+
| `ssr-react-swc-ts` | |
|
|
73
|
+
| `ssr-preact` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-preact) |
|
|
74
|
+
| `ssr-preact-ts` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-preact-ts) |
|
|
75
|
+
| `ssr-svelte` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-svelte) |
|
|
76
|
+
| `ssr-svelte-ts` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-svelte-ts) |
|
|
77
|
+
| `deno-vanilla` | |
|
|
78
|
+
| `deno-vanilla-ts` | |
|
|
79
|
+
| `deno-vue` | |
|
|
80
|
+
| `deno-vue-ts` | |
|
|
81
|
+
| `deno-react` | |
|
|
82
|
+
| `deno-react-ts` | |
|
|
83
|
+
| `deno-react-swc` | |
|
|
84
|
+
| `deno-react-swc-ts` | |
|
|
85
|
+
| `deno-preact` | |
|
|
86
|
+
| `deno-preact-ts` | |
|
|
87
|
+
| `deno-lit` | |
|
|
88
|
+
| `deno-lit-ts` | |
|
|
89
|
+
| `deno-svelte` | |
|
|
90
|
+
| `deno-svelte-ts` | |
|
|
91
|
+
| `library` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-library) |
|
|
92
|
+
| `library-ts` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-library-ts) |
|
|
93
|
+
| `ssr-transform` | [StackBlitz](https://stackblitz.com/fork/github/bluwy/create-vite-extra/tree/master/template-ssr-transform) |
|
|
92
94
|
|
|
93
95
|
You can use `.` for the project name to scaffold in the current directory.
|
|
94
96
|
|
package/index.js
CHANGED
|
@@ -46,14 +46,38 @@ const FRAMEWORKS = [
|
|
|
46
46
|
color: green,
|
|
47
47
|
variants: [
|
|
48
48
|
{
|
|
49
|
-
name: 'ssr-vue',
|
|
50
|
-
display: '
|
|
51
|
-
color:
|
|
49
|
+
name: 'ssr-vue-streaming',
|
|
50
|
+
display: 'Streaming',
|
|
51
|
+
color: green,
|
|
52
|
+
variants: [
|
|
53
|
+
{
|
|
54
|
+
name: 'ssr-vue-streaming',
|
|
55
|
+
display: 'JavaScript',
|
|
56
|
+
color: yellow
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'ssr-vue-streaming-ts',
|
|
60
|
+
display: 'TypeScript',
|
|
61
|
+
color: blue
|
|
62
|
+
}
|
|
63
|
+
]
|
|
52
64
|
},
|
|
53
65
|
{
|
|
54
|
-
name: 'ssr-vue
|
|
55
|
-
display: '
|
|
56
|
-
color:
|
|
66
|
+
name: 'ssr-vue',
|
|
67
|
+
display: 'Non-streaming',
|
|
68
|
+
color: green,
|
|
69
|
+
variants: [
|
|
70
|
+
{
|
|
71
|
+
name: 'ssr-vue',
|
|
72
|
+
display: 'JavaScript',
|
|
73
|
+
color: yellow
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'ssr-vue-ts',
|
|
77
|
+
display: 'TypeScript',
|
|
78
|
+
color: blue
|
|
79
|
+
}
|
|
80
|
+
]
|
|
57
81
|
}
|
|
58
82
|
]
|
|
59
83
|
},
|
|
@@ -354,6 +378,23 @@ async function init() {
|
|
|
354
378
|
}
|
|
355
379
|
})
|
|
356
380
|
},
|
|
381
|
+
// Variant 1
|
|
382
|
+
{
|
|
383
|
+
type: (framework) =>
|
|
384
|
+
framework && framework.variants ? 'select' : null,
|
|
385
|
+
name: 'variant',
|
|
386
|
+
message: reset('Select a variant:'),
|
|
387
|
+
// @ts-ignore
|
|
388
|
+
choices: (framework) =>
|
|
389
|
+
framework.variants.map((variant) => {
|
|
390
|
+
const variantColor = variant.color
|
|
391
|
+
return {
|
|
392
|
+
title: variantColor(variant.display || variant.name),
|
|
393
|
+
value: variant.variants ? variant : variant.name
|
|
394
|
+
}
|
|
395
|
+
})
|
|
396
|
+
},
|
|
397
|
+
// Variant 2
|
|
357
398
|
{
|
|
358
399
|
type: (framework) =>
|
|
359
400
|
framework && framework.variants ? 'select' : null,
|
package/package.json
CHANGED
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -60,7 +60,7 @@ app.use('*', async (req, res) => {
|
|
|
60
60
|
.replace(`<!--app-head-->`, head)
|
|
61
61
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
62
62
|
|
|
63
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
63
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
64
64
|
} catch (e) {
|
|
65
65
|
vite?.ssrFixStacktrace(e)
|
|
66
66
|
console.log(e.stack)
|
|
@@ -60,7 +60,7 @@ app.use('*', async (req, res) => {
|
|
|
60
60
|
.replace(`<!--app-head-->`, head)
|
|
61
61
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
62
62
|
|
|
63
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
63
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
64
64
|
} catch (e) {
|
|
65
65
|
vite?.ssrFixStacktrace(e)
|
|
66
66
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Vue 3 + Vite
|
|
2
|
+
|
|
3
|
+
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
|
4
|
+
|
|
5
|
+
## Recommended IDE Setup
|
|
6
|
+
|
|
7
|
+
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
|
|
15
|
+
# Editor directories and files
|
|
16
|
+
.vscode/*
|
|
17
|
+
!.vscode/extensions.json
|
|
18
|
+
.idea
|
|
19
|
+
.DS_Store
|
|
20
|
+
*.suo
|
|
21
|
+
*.ntvs*
|
|
22
|
+
*.njsproj
|
|
23
|
+
*.sln
|
|
24
|
+
*.sw?
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + Vue</title>
|
|
8
|
+
<!--app-head-->
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="app"><!--app-html--></div>
|
|
12
|
+
<script type="module" src="/src/entry-client.js"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-vue-starter",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "node server",
|
|
8
|
+
"build": "npm run build:client && npm run build:server",
|
|
9
|
+
"build:client": "vite build --ssrManifest --outDir dist/client",
|
|
10
|
+
"build:server": "vite build --ssr src/entry-server.js --outDir dist/server",
|
|
11
|
+
"preview": "cross-env NODE_ENV=production node server"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"compression": "^1.7.4",
|
|
15
|
+
"express": "^4.18.2",
|
|
16
|
+
"sirv": "^2.0.4",
|
|
17
|
+
"vue": "^3.3.13"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@vitejs/plugin-vue": "^4.5.2",
|
|
21
|
+
"cross-env": "^7.0.3",
|
|
22
|
+
"vite": "^5.0.10"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import express from 'express'
|
|
3
|
+
|
|
4
|
+
// Constants
|
|
5
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
6
|
+
const port = process.env.PORT || 5173
|
|
7
|
+
const base = process.env.BASE || '/'
|
|
8
|
+
|
|
9
|
+
// Cached production assets
|
|
10
|
+
const templateHtml = isProduction
|
|
11
|
+
? await fs.readFile('./dist/client/index.html', 'utf-8')
|
|
12
|
+
: ''
|
|
13
|
+
const ssrManifest = isProduction
|
|
14
|
+
? await fs.readFile('./dist/client/.vite/ssr-manifest.json', 'utf-8')
|
|
15
|
+
: undefined
|
|
16
|
+
|
|
17
|
+
// Create http server
|
|
18
|
+
const app = express()
|
|
19
|
+
|
|
20
|
+
// Add Vite or respective production middlewares
|
|
21
|
+
let vite
|
|
22
|
+
if (!isProduction) {
|
|
23
|
+
const { createServer } = await import('vite')
|
|
24
|
+
vite = await createServer({
|
|
25
|
+
server: { middlewareMode: true },
|
|
26
|
+
appType: 'custom',
|
|
27
|
+
base
|
|
28
|
+
})
|
|
29
|
+
app.use(vite.middlewares)
|
|
30
|
+
} else {
|
|
31
|
+
const compression = (await import('compression')).default
|
|
32
|
+
const sirv = (await import('sirv')).default
|
|
33
|
+
app.use(compression())
|
|
34
|
+
app.use(base, sirv('./dist/client', { extensions: [] }))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Serve HTML
|
|
38
|
+
app.use('*', async (req, res) => {
|
|
39
|
+
try {
|
|
40
|
+
const url = req.originalUrl.replace(base, '')
|
|
41
|
+
|
|
42
|
+
let template
|
|
43
|
+
let render
|
|
44
|
+
if (!isProduction) {
|
|
45
|
+
// Always read fresh template in development
|
|
46
|
+
template = await fs.readFile('./index.html', 'utf-8')
|
|
47
|
+
template = await vite.transformIndexHtml(url, template)
|
|
48
|
+
render = (await vite.ssrLoadModule('/src/entry-server.js')).render
|
|
49
|
+
} else {
|
|
50
|
+
template = templateHtml
|
|
51
|
+
render = (await import('./dist/server/entry-server.js')).render
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { stream } = render(url, ssrManifest)
|
|
55
|
+
|
|
56
|
+
const [htmlStart, htmlEnd] = template.split('<!--app-html-->')
|
|
57
|
+
|
|
58
|
+
res.status(200).set({ 'Content-Type': 'text/html' })
|
|
59
|
+
|
|
60
|
+
res.write(htmlStart)
|
|
61
|
+
for await (const chunk of stream) {
|
|
62
|
+
if (res.closed) break
|
|
63
|
+
res.write(chunk)
|
|
64
|
+
}
|
|
65
|
+
res.write(htmlEnd)
|
|
66
|
+
res.end()
|
|
67
|
+
} catch (e) {
|
|
68
|
+
vite?.ssrFixStacktrace(e)
|
|
69
|
+
console.log(e.stack)
|
|
70
|
+
res.status(500).end(e.stack)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// Start http server
|
|
75
|
+
app.listen(port, () => {
|
|
76
|
+
console.log(`Server started at http://localhost:${port}`)
|
|
77
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
// This starter template is using Vue 3 <script setup> SFCs
|
|
3
|
+
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
|
|
4
|
+
import HelloWorld from './components/HelloWorld.vue'
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div>
|
|
9
|
+
<a href="https://vitejs.dev" target="_blank">
|
|
10
|
+
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://vuejs.org/" target="_blank">
|
|
13
|
+
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
|
14
|
+
</a>
|
|
15
|
+
</div>
|
|
16
|
+
<HelloWorld msg="Vite + Vue" />
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<style scoped>
|
|
20
|
+
.logo {
|
|
21
|
+
height: 6em;
|
|
22
|
+
padding: 1.5em;
|
|
23
|
+
will-change: filter;
|
|
24
|
+
}
|
|
25
|
+
.logo:hover {
|
|
26
|
+
filter: drop-shadow(0 0 2em #646cffaa);
|
|
27
|
+
}
|
|
28
|
+
.logo.vue:hover {
|
|
29
|
+
filter: drop-shadow(0 0 2em #42b883aa);
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
defineProps({
|
|
5
|
+
msg: String
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
const count = ref(0)
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<h1>{{ msg }}</h1>
|
|
13
|
+
|
|
14
|
+
<div class="card">
|
|
15
|
+
<button type="button" @click="count++">count is {{ count }}</button>
|
|
16
|
+
<p>
|
|
17
|
+
Edit
|
|
18
|
+
<code>components/HelloWorld.vue</code> to test HMR
|
|
19
|
+
</p>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<p>
|
|
23
|
+
Check out
|
|
24
|
+
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
|
25
|
+
>create-vue</a
|
|
26
|
+
>, the official Vue + Vite starter
|
|
27
|
+
</p>
|
|
28
|
+
<p>
|
|
29
|
+
Install
|
|
30
|
+
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
|
|
31
|
+
in your IDE for a better DX
|
|
32
|
+
</p>
|
|
33
|
+
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<style scoped>
|
|
37
|
+
.read-the-docs {
|
|
38
|
+
color: #888;
|
|
39
|
+
}
|
|
40
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { renderToWebStream } from 'vue/server-renderer'
|
|
2
|
+
import { createApp } from './main'
|
|
3
|
+
|
|
4
|
+
export function render() {
|
|
5
|
+
const { app } = createApp()
|
|
6
|
+
|
|
7
|
+
// passing SSR context object which will be available via useSSRContext()
|
|
8
|
+
// @vitejs/plugin-vue injects code into a component's setup() that registers
|
|
9
|
+
// itself on ctx.modules. After the render, ctx.modules would contain all the
|
|
10
|
+
// components that have been instantiated during this render call.
|
|
11
|
+
const ctx = {}
|
|
12
|
+
const stream = renderToWebStream(app, ctx)
|
|
13
|
+
|
|
14
|
+
return { stream }
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createSSRApp } from 'vue'
|
|
2
|
+
import App from './App.vue'
|
|
3
|
+
|
|
4
|
+
// SSR requires a fresh app instance per request, therefore we export a function
|
|
5
|
+
// that creates a fresh app instance. If using Vuex, we'd also be creating a
|
|
6
|
+
// fresh store here.
|
|
7
|
+
export function createApp() {
|
|
8
|
+
const app = createSSRApp(App)
|
|
9
|
+
return { app }
|
|
10
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
a {
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
color: #646cff;
|
|
19
|
+
text-decoration: inherit;
|
|
20
|
+
}
|
|
21
|
+
a:hover {
|
|
22
|
+
color: #535bf2;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
body {
|
|
26
|
+
margin: 0;
|
|
27
|
+
display: flex;
|
|
28
|
+
place-items: center;
|
|
29
|
+
min-width: 320px;
|
|
30
|
+
min-height: 100vh;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
h1 {
|
|
34
|
+
font-size: 3.2em;
|
|
35
|
+
line-height: 1.1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button {
|
|
39
|
+
border-radius: 8px;
|
|
40
|
+
border: 1px solid transparent;
|
|
41
|
+
padding: 0.6em 1.2em;
|
|
42
|
+
font-size: 1em;
|
|
43
|
+
font-weight: 500;
|
|
44
|
+
font-family: inherit;
|
|
45
|
+
background-color: #1a1a1a;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
transition: border-color 0.25s;
|
|
48
|
+
}
|
|
49
|
+
button:hover {
|
|
50
|
+
border-color: #646cff;
|
|
51
|
+
}
|
|
52
|
+
button:focus,
|
|
53
|
+
button:focus-visible {
|
|
54
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.card {
|
|
58
|
+
padding: 2em;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#app {
|
|
62
|
+
max-width: 1280px;
|
|
63
|
+
margin: 0 auto;
|
|
64
|
+
padding: 2rem;
|
|
65
|
+
text-align: center;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@media (prefers-color-scheme: light) {
|
|
69
|
+
:root {
|
|
70
|
+
color: #213547;
|
|
71
|
+
background-color: #ffffff;
|
|
72
|
+
}
|
|
73
|
+
a:hover {
|
|
74
|
+
color: #747bff;
|
|
75
|
+
}
|
|
76
|
+
button {
|
|
77
|
+
background-color: #f9f9f9;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Vue 3 + TypeScript + Vite
|
|
2
|
+
|
|
3
|
+
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
|
4
|
+
|
|
5
|
+
## Recommended IDE Setup
|
|
6
|
+
|
|
7
|
+
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
|
8
|
+
|
|
9
|
+
## Type Support For `.vue` Imports in TS
|
|
10
|
+
|
|
11
|
+
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
|
12
|
+
|
|
13
|
+
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
|
14
|
+
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
|
|
15
|
+
|
|
16
|
+
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
|
|
15
|
+
# Editor directories and files
|
|
16
|
+
.vscode/*
|
|
17
|
+
!.vscode/extensions.json
|
|
18
|
+
.idea
|
|
19
|
+
.DS_Store
|
|
20
|
+
*.suo
|
|
21
|
+
*.ntvs*
|
|
22
|
+
*.njsproj
|
|
23
|
+
*.sln
|
|
24
|
+
*.sw?
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + Vue + TS</title>
|
|
8
|
+
<!--app-head-->
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="app"><!--app-html--></div>
|
|
12
|
+
<script type="module" src="/src/entry-client.ts"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-vue-typescript-starter",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "node server",
|
|
8
|
+
"build": "npm run build:client && npm run build:server",
|
|
9
|
+
"build:client": "vite build --ssrManifest --outDir dist/client",
|
|
10
|
+
"build:server": "vite build --ssr src/entry-server.ts --outDir dist/server",
|
|
11
|
+
"preview": "cross-env NODE_ENV=production node server"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"compression": "^1.7.4",
|
|
15
|
+
"express": "^4.18.2",
|
|
16
|
+
"sirv": "^2.0.4",
|
|
17
|
+
"vue": "^3.3.13"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/express": "^4.17.21",
|
|
21
|
+
"@types/node": "^20.10.5",
|
|
22
|
+
"@vitejs/plugin-vue": "^4.5.2",
|
|
23
|
+
"cross-env": "^7.0.3",
|
|
24
|
+
"typescript": "^5.3.3",
|
|
25
|
+
"vite": "^5.0.10",
|
|
26
|
+
"vue-tsc": "^1.8.26"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import express from 'express'
|
|
3
|
+
|
|
4
|
+
// Constants
|
|
5
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
6
|
+
const port = process.env.PORT || 5173
|
|
7
|
+
const base = process.env.BASE || '/'
|
|
8
|
+
|
|
9
|
+
// Cached production assets
|
|
10
|
+
const templateHtml = isProduction
|
|
11
|
+
? await fs.readFile('./dist/client/index.html', 'utf-8')
|
|
12
|
+
: ''
|
|
13
|
+
const ssrManifest = isProduction
|
|
14
|
+
? await fs.readFile('./dist/client/.vite/ssr-manifest.json', 'utf-8')
|
|
15
|
+
: undefined
|
|
16
|
+
|
|
17
|
+
// Create http server
|
|
18
|
+
const app = express()
|
|
19
|
+
|
|
20
|
+
// Add Vite or respective production middlewares
|
|
21
|
+
let vite
|
|
22
|
+
if (!isProduction) {
|
|
23
|
+
const { createServer } = await import('vite')
|
|
24
|
+
vite = await createServer({
|
|
25
|
+
server: { middlewareMode: true },
|
|
26
|
+
appType: 'custom',
|
|
27
|
+
base
|
|
28
|
+
})
|
|
29
|
+
app.use(vite.middlewares)
|
|
30
|
+
} else {
|
|
31
|
+
const compression = (await import('compression')).default
|
|
32
|
+
const sirv = (await import('sirv')).default
|
|
33
|
+
app.use(compression())
|
|
34
|
+
app.use(base, sirv('./dist/client', { extensions: [] }))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Serve HTML
|
|
38
|
+
app.use('*', async (req, res) => {
|
|
39
|
+
try {
|
|
40
|
+
const url = req.originalUrl.replace(base, '')
|
|
41
|
+
|
|
42
|
+
let template
|
|
43
|
+
let render
|
|
44
|
+
if (!isProduction) {
|
|
45
|
+
// Always read fresh template in development
|
|
46
|
+
template = await fs.readFile('./index.html', 'utf-8')
|
|
47
|
+
template = await vite.transformIndexHtml(url, template)
|
|
48
|
+
render = (await vite.ssrLoadModule('/src/entry-server.ts')).render
|
|
49
|
+
} else {
|
|
50
|
+
template = templateHtml
|
|
51
|
+
render = (await import('./dist/server/entry-server.js')).render
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { stream } = render(url, ssrManifest)
|
|
55
|
+
|
|
56
|
+
const [htmlStart, htmlEnd] = template.split('<!--app-html-->')
|
|
57
|
+
|
|
58
|
+
res.status(200).set({ 'Content-Type': 'text/html' })
|
|
59
|
+
|
|
60
|
+
res.write(htmlStart)
|
|
61
|
+
for await (const chunk of stream) {
|
|
62
|
+
if (res.closed) break
|
|
63
|
+
res.write(chunk)
|
|
64
|
+
}
|
|
65
|
+
res.write(htmlEnd)
|
|
66
|
+
res.end()
|
|
67
|
+
} catch (e) {
|
|
68
|
+
vite?.ssrFixStacktrace(e)
|
|
69
|
+
console.log(e.stack)
|
|
70
|
+
res.status(500).end(e.stack)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// Start http server
|
|
75
|
+
app.listen(port, () => {
|
|
76
|
+
console.log(`Server started at http://localhost:${port}`)
|
|
77
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// This starter template is using Vue 3 <script setup> SFCs
|
|
3
|
+
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
|
|
4
|
+
import HelloWorld from './components/HelloWorld.vue'
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div>
|
|
9
|
+
<a href="https://vitejs.dev" target="_blank">
|
|
10
|
+
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://vuejs.org/" target="_blank">
|
|
13
|
+
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
|
14
|
+
</a>
|
|
15
|
+
</div>
|
|
16
|
+
<HelloWorld msg="Vite + Vue" />
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<style scoped>
|
|
20
|
+
.logo {
|
|
21
|
+
height: 6em;
|
|
22
|
+
padding: 1.5em;
|
|
23
|
+
will-change: filter;
|
|
24
|
+
}
|
|
25
|
+
.logo:hover {
|
|
26
|
+
filter: drop-shadow(0 0 2em #646cffaa);
|
|
27
|
+
}
|
|
28
|
+
.logo.vue:hover {
|
|
29
|
+
filter: drop-shadow(0 0 2em #42b883aa);
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
defineProps<{ msg: string }>()
|
|
5
|
+
|
|
6
|
+
const count = ref(0)
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<h1>{{ msg }}</h1>
|
|
11
|
+
|
|
12
|
+
<div class="card">
|
|
13
|
+
<button type="button" @click="count++">count is {{ count }}</button>
|
|
14
|
+
<p>
|
|
15
|
+
Edit
|
|
16
|
+
<code>components/HelloWorld.vue</code> to test HMR
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<p>
|
|
21
|
+
Check out
|
|
22
|
+
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
|
23
|
+
>create-vue</a
|
|
24
|
+
>, the official Vue + Vite starter
|
|
25
|
+
</p>
|
|
26
|
+
<p>
|
|
27
|
+
Install
|
|
28
|
+
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
|
|
29
|
+
in your IDE for a better DX
|
|
30
|
+
</p>
|
|
31
|
+
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<style scoped>
|
|
35
|
+
.read-the-docs {
|
|
36
|
+
color: #888;
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { renderToWebStream } from 'vue/server-renderer'
|
|
2
|
+
import { createApp } from './main'
|
|
3
|
+
|
|
4
|
+
export function render() {
|
|
5
|
+
const { app } = createApp()
|
|
6
|
+
|
|
7
|
+
// passing SSR context object which will be available via useSSRContext()
|
|
8
|
+
// @vitejs/plugin-vue injects code into a component's setup() that registers
|
|
9
|
+
// itself on ctx.modules. After the render, ctx.modules would contain all the
|
|
10
|
+
// components that have been instantiated during this render call.
|
|
11
|
+
const ctx = {}
|
|
12
|
+
const stream = renderToWebStream(app, ctx)
|
|
13
|
+
|
|
14
|
+
return { stream }
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createSSRApp } from 'vue'
|
|
2
|
+
import App from './App.vue'
|
|
3
|
+
|
|
4
|
+
// SSR requires a fresh app instance per request, therefore we export a function
|
|
5
|
+
// that creates a fresh app instance. If using Vuex, we'd also be creating a
|
|
6
|
+
// fresh store here.
|
|
7
|
+
export function createApp() {
|
|
8
|
+
const app = createSSRApp(App)
|
|
9
|
+
return { app }
|
|
10
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
a {
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
color: #646cff;
|
|
19
|
+
text-decoration: inherit;
|
|
20
|
+
}
|
|
21
|
+
a:hover {
|
|
22
|
+
color: #535bf2;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
body {
|
|
26
|
+
margin: 0;
|
|
27
|
+
display: flex;
|
|
28
|
+
place-items: center;
|
|
29
|
+
min-width: 320px;
|
|
30
|
+
min-height: 100vh;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
h1 {
|
|
34
|
+
font-size: 3.2em;
|
|
35
|
+
line-height: 1.1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button {
|
|
39
|
+
border-radius: 8px;
|
|
40
|
+
border: 1px solid transparent;
|
|
41
|
+
padding: 0.6em 1.2em;
|
|
42
|
+
font-size: 1em;
|
|
43
|
+
font-weight: 500;
|
|
44
|
+
font-family: inherit;
|
|
45
|
+
background-color: #1a1a1a;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
transition: border-color 0.25s;
|
|
48
|
+
}
|
|
49
|
+
button:hover {
|
|
50
|
+
border-color: #646cff;
|
|
51
|
+
}
|
|
52
|
+
button:focus,
|
|
53
|
+
button:focus-visible {
|
|
54
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.card {
|
|
58
|
+
padding: 2em;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#app {
|
|
62
|
+
max-width: 1280px;
|
|
63
|
+
margin: 0 auto;
|
|
64
|
+
padding: 2rem;
|
|
65
|
+
text-align: center;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@media (prefers-color-scheme: light) {
|
|
69
|
+
:root {
|
|
70
|
+
color: #213547;
|
|
71
|
+
background-color: #ffffff;
|
|
72
|
+
}
|
|
73
|
+
a:hover {
|
|
74
|
+
color: #747bff;
|
|
75
|
+
}
|
|
76
|
+
button {
|
|
77
|
+
background-color: #f9f9f9;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "Bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "preserve",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
|
|
24
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
25
|
+
}
|
|
@@ -57,7 +57,7 @@ app.use('*', async (req, res) => {
|
|
|
57
57
|
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
58
58
|
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
59
59
|
|
|
60
|
-
res.status(200).set({ 'Content-Type': 'text/html' }).
|
|
60
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
61
61
|
} catch (e) {
|
|
62
62
|
vite?.ssrFixStacktrace(e)
|
|
63
63
|
console.log(e.stack)
|