create-esmx 3.0.0-rc.47 → 3.0.0-rc.48

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-esmx",
3
- "version": "3.0.0-rc.47",
3
+ "version": "3.0.0-rc.48",
4
4
  "description": "A scaffold tool for creating Esmx projects",
5
5
  "type": "module",
6
6
  "private": false,
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "@biomejs/biome": "1.9.4",
27
- "@esmx/lint": "3.0.0-rc.47",
27
+ "@esmx/lint": "3.0.0-rc.48",
28
28
  "@types/minimist": "^1.2.5",
29
29
  "@types/node": "^24.0.0",
30
30
  "@vitest/coverage-v8": "3.2.4",
@@ -69,5 +69,5 @@
69
69
  "url": "https://github.com/esmnext/esmx/issues"
70
70
  },
71
71
  "homepage": "https://github.com/esmnext/esmx#readme",
72
- "gitHead": "3e55424b9029d259537a802032f3a1f54b6fb1e8"
72
+ "gitHead": "162ec15d59c5f38c477e78101efa689844d593e2"
73
73
  }
@@ -0,0 +1,80 @@
1
+ # {{projectName}}
2
+
3
+ An Esmx project with Vue and Client-Side Rendering.
4
+
5
+ ## 📦 Tech Stack
6
+
7
+ - **Framework**: [Esmx](https://esmnext.com) - Next generation micro-frontend framework based on native ESM
8
+ - **UI Framework**: Vue
9
+ - **Build Tool**: Rspack
10
+ - **Type Checking**: TypeScript
11
+ - **Rendering Mode**: Client-Side Rendering (CSR)
12
+
13
+ ## 🚀 Quick Start
14
+
15
+ ### Install Dependencies
16
+
17
+ ```bash
18
+ {{installCommand}}
19
+ ```
20
+
21
+ ### Development Environment
22
+
23
+ ```bash
24
+ {{devCommand}}
25
+ ```
26
+
27
+ Visit http://localhost:3000 to see the development environment.
28
+
29
+ ### Production Build
30
+
31
+ ```bash
32
+ {{buildCommand}}
33
+ ```
34
+
35
+ ### Start Production Server
36
+
37
+ ```bash
38
+ {{startCommand}}
39
+ ```
40
+
41
+ ### Type Generation
42
+
43
+ ```bash
44
+ {{buildTypeCommand}}
45
+ ```
46
+
47
+ ### Type Checking
48
+
49
+ ```bash
50
+ {{lintTypeCommand}}
51
+ ```
52
+
53
+ ## 📁 Project Structure
54
+
55
+ ```
56
+ {{projectName}}/
57
+ ├── src/
58
+ │ ├── app.vue # Main application component with Esmx and Vue logos
59
+ │ ├── components/ # UI components
60
+ │ │ └── hello-world.vue # Example component with counter functionality
61
+ │ ├── create-app.ts # Vue instance creation
62
+ │ ├── entry.client.ts # Client-side entry
63
+ │ ├── entry.node.ts # Node.js environment entry point
64
+ │ └── entry.server.ts # Server-side rendering functions
65
+ ├── package.json
66
+ ├── tsconfig.json
67
+ └── README.md
68
+ ```
69
+
70
+ ## 🔧 Configuration Details
71
+
72
+ - `entry.client.ts` - Responsible for client-side interaction and dynamic updates
73
+ - `entry.node.ts` - Handles server-side rendering and development server configuration
74
+ - `entry.server.ts` - Manages server-side rendering process and HTML generation
75
+
76
+ ## 📚 Additional Resources
77
+
78
+ - [Esmx Official Documentation](https://esmnext.com)
79
+ - [Vue Documentation](https://vuejs.org)
80
+ - [TypeScript Documentation](https://www.typescriptlang.org)
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "1.0.0",
4
+ "description": "Vue Client-Side Rendering framework",
5
+ "type": "module",
6
+ "private": true,
7
+ "scripts": {
8
+ "dev": "esmx dev",
9
+ "build": "esmx build",
10
+ "preview": "esmx preview",
11
+ "start": "esmx start",
12
+ "lint:type": "vue-tsc --noEmit",
13
+ "build:type": "vue-tsc --declaration --emitDeclarationOnly --noEmit false --outDir dist/src && tsc-alias -p tsconfig.json --outDir dist/src"
14
+ },
15
+ "dependencies": {
16
+ "@esmx/core": "{{esmxVersion}}"
17
+ },
18
+ "devDependencies": {
19
+ "tsc-alias": "^1.8.16",
20
+ "@esmx/rspack-vue": "{{esmxVersion}}",
21
+ "@types/node": "^24.0.0",
22
+ "vue": "^3.5.18",
23
+ "typescript": "5.8.3",
24
+ "vue-tsc": "^3.0.1"
25
+ }
26
+ }
@@ -0,0 +1,127 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+ import HelloWorld from './components/hello-world.vue';
4
+
5
+ const title = ref<string>('Vue CSR Demo');
6
+ </script>
7
+
8
+ <template>
9
+ <div class="container">
10
+ <div class="logo-container">
11
+ <a href="https://www.esmnext.com" target="_blank" class="logo-link">
12
+ <div class="logo-wrapper esmx">
13
+ <img src="https://www.esmnext.com/logo.svg" class="logo" alt="Esmx logo" />
14
+ </div>
15
+ </a>
16
+ <a href="https://vuejs.org/" target="_blank" class="logo-link">
17
+ <div class="logo-wrapper vue">
18
+ <img src="https://vuejs.org/logo.svg" class="logo" alt="Vue logo" />
19
+ </div>
20
+ </a>
21
+ </div>
22
+ <HelloWorld :msg="title" />
23
+ </div>
24
+ </template>
25
+
26
+ <style>
27
+ :root {
28
+ --esmx-primary: #001137;
29
+ --esmx-secondary: #273498;
30
+ --esmx-accent: #0074C2;
31
+ --esmx-light: #00ABE7;
32
+ --esmx-sun-core: #FFA000;
33
+ --esmx-sun-rays: #FFC107;
34
+ --vue-color: #42b883;
35
+ --vue-dark: #33a06f;
36
+ --border-color: rgba(0, 17, 55, 0.12);
37
+ --shadow-color: rgba(0, 17, 55, 0.05);
38
+ --text-primary: #213547;
39
+ --text-secondary: #666;
40
+ --bg-card: #fcfcfc;
41
+ --bg-hover: rgba(255, 250, 240, 0.8);
42
+ --font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
43
+ }
44
+
45
+ body {
46
+ margin: 0;
47
+ font-family: var(--font-family);
48
+ color: var(--text-primary);
49
+ background-color: white;
50
+ line-height: 1.6;
51
+ -webkit-font-smoothing: antialiased;
52
+ -moz-osx-font-smoothing: grayscale;
53
+ }
54
+ </style>
55
+
56
+ <style scoped>
57
+ .container {
58
+ max-width: 1280px;
59
+ margin: 0 auto;
60
+ padding: 2rem;
61
+ text-align: center;
62
+ font-family: var(--font-family);
63
+ }
64
+
65
+ .logo-container {
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ gap: 3.5rem;
70
+ margin-bottom: 3rem;
71
+ }
72
+
73
+ .logo-link {
74
+ text-decoration: none;
75
+ position: relative;
76
+ }
77
+
78
+ .logo-wrapper {
79
+ display: flex;
80
+ justify-content: center;
81
+ align-items: center;
82
+ width: 6.5em;
83
+ height: 6.5em;
84
+ border-radius: 12px;
85
+ background-color: var(--bg-card);
86
+ padding: 1em;
87
+ box-shadow: 0 2px 12px var(--shadow-color);
88
+ border: 1px solid var(--border-color);
89
+ transition: all 0.3s ease;
90
+ }
91
+
92
+ .logo-wrapper:hover {
93
+ transform: translateY(-5px);
94
+ box-shadow: 0 5px 15px var(--shadow-color);
95
+ }
96
+
97
+ .logo {
98
+ height: 100%;
99
+ width: auto;
100
+ transition: transform 0.3s ease;
101
+ }
102
+
103
+ .logo-wrapper:hover .logo {
104
+ transform: scale(1.1);
105
+ }
106
+
107
+ .logo-wrapper.esmx:hover {
108
+ background-color: rgba(255, 192, 7, 0.1);
109
+ border-color: var(--esmx-sun-rays);
110
+ }
111
+
112
+ .logo-wrapper.vue:hover {
113
+ background-color: rgba(66, 184, 131, 0.1);
114
+ border-color: var(--vue-color);
115
+ }
116
+
117
+ @media (max-width: 768px) {
118
+ .logo-container {
119
+ gap: 2rem;
120
+ }
121
+
122
+ .logo-wrapper {
123
+ width: 5em;
124
+ height: 5em;
125
+ }
126
+ }
127
+ </style>
@@ -0,0 +1,77 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+
4
+ defineProps({
5
+ msg: {
6
+ type: String
7
+ }
8
+ });
9
+ const count = ref<number>(0);
10
+ </script>
11
+
12
+ <template>
13
+ <div>
14
+ <h1>{{ msg }}</h1>
15
+
16
+ <div class="card">
17
+ <button type="button" @click="count++">Counter: {{ count }}</button>
18
+ <p>
19
+ Edit
20
+ <code>components/HelloWorld.vue</code> to test HMR
21
+ </p>
22
+ </div>
23
+
24
+ <p>Experience Vue with client-side rendering powered by Esmx framework</p>
25
+ </div>
26
+ </template>
27
+
28
+ <style scoped>
29
+ .card {
30
+ padding: 2em;
31
+ border-radius: 12px;
32
+ margin: 2.5em 0;
33
+ background-color: var(--bg-card);
34
+ }
35
+
36
+ button {
37
+ border-radius: 8px;
38
+ border: 1px solid transparent;
39
+ padding: 0.6em 1.2em;
40
+ font-size: 1em;
41
+ font-weight: 600;
42
+ font-family: inherit;
43
+ background-color: var(--esmx-sun-rays);
44
+ color: #fff;
45
+ cursor: pointer;
46
+ margin-bottom: 1em;
47
+ transition: all 0.25s ease;
48
+ }
49
+
50
+ button:hover {
51
+ background-color: var(--esmx-sun-core);
52
+ transform: translateY(-1px);
53
+ box-shadow: 0 4px 8px rgba(255, 160, 0, 0.25);
54
+ }
55
+
56
+ h1 {
57
+ font-size: 3.2em;
58
+ line-height: 1.1;
59
+ margin-bottom: 1em;
60
+ color: var(--esmx-primary);
61
+ font-weight: 700;
62
+ }
63
+
64
+ p {
65
+ line-height: 1.6;
66
+ margin: 0.5em 0;
67
+ color: var(--text-primary);
68
+ }
69
+
70
+ code {
71
+ background-color: rgba(0, 116, 194, 0.1);
72
+ padding: 0.2em 0.4em;
73
+ border-radius: 4px;
74
+ font-family: monospace;
75
+ font-size: 0.9em;
76
+ }
77
+ </style>
@@ -0,0 +1,9 @@
1
+ import { createApp } from 'vue';
2
+ import App from './app.vue';
3
+
4
+ export function createVueApp() {
5
+ const app = createApp(App);
6
+ return {
7
+ app
8
+ };
9
+ }
@@ -0,0 +1,5 @@
1
+ import { createVueApp } from './create-app';
2
+
3
+ const { app } = createVueApp();
4
+
5
+ app.mount('#app');
@@ -0,0 +1,35 @@
1
+ import http from 'node:http';
2
+ import type { EsmxOptions } from '@esmx/core';
3
+
4
+ export default {
5
+ modules: {
6
+ exports: ['npm:vue']
7
+ },
8
+ async devApp(esmx) {
9
+ return import('@esmx/rspack-vue').then((m) =>
10
+ m.createRspackVue3App(esmx, {
11
+ chain(context) {
12
+ // Custom Rspack configuration
13
+ }
14
+ })
15
+ );
16
+ },
17
+ async postBuild(esmx) {
18
+ const rc = await esmx.render();
19
+ esmx.writeSync(esmx.resolvePath('dist/client', 'index.html'), rc.html);
20
+ },
21
+ async server(esmx) {
22
+ const server = http.createServer((req, res) => {
23
+ esmx.middleware(req, res, async () => {
24
+ const rc = await esmx.render({
25
+ params: { url: req.url }
26
+ });
27
+ res.end(rc.html);
28
+ });
29
+ });
30
+
31
+ server.listen(3000, () => {
32
+ console.log('Server started: http://localhost:3000');
33
+ });
34
+ }
35
+ } satisfies EsmxOptions;
@@ -0,0 +1,26 @@
1
+ import type { RenderContext } from '@esmx/core';
2
+
3
+ export default async (rc: RenderContext) => {
4
+ await rc.commit();
5
+
6
+ rc.html = `<!DOCTYPE html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8">
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
+ <meta name="description" content="Vue with Client-Side Rendering powered by Esmx framework">
12
+ <meta name="keywords" content="Vue, CSR, Client-Side Rendering, Esmx, Vue.js, JavaScript, TypeScript, Rspack">
13
+ <link rel="icon" href="https://www.esmnext.com/logo.svg" type="image/svg+xml">
14
+ ${rc.preload()}
15
+ <title>Vue CSR Demo | Powered by Esmx</title>
16
+ ${rc.css()}
17
+ </head>
18
+ <body>
19
+ <div id="app"></div>
20
+ ${rc.importmap()}
21
+ ${rc.moduleEntry()}
22
+ ${rc.modulePreload()}
23
+ </body>
24
+ </html>
25
+ `;
26
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "ESNext",
4
+ "moduleResolution": "node",
5
+ "isolatedModules": true,
6
+ "resolveJsonModule": true,
7
+
8
+ "target": "ESNext",
9
+ "lib": ["ESNext", "DOM"],
10
+
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "types": ["@types/node"],
14
+
15
+ "experimentalDecorators": true,
16
+ "allowSyntheticDefaultImports": true,
17
+
18
+ "baseUrl": ".",
19
+ "paths": {
20
+ "{{projectName}}/src/*": ["./src/*"],
21
+ "{{projectName}}/*": ["./*"]
22
+ }
23
+ },
24
+ "include": ["src"],
25
+ "exclude": ["dist", "node_modules"]
26
+ }
@@ -0,0 +1,80 @@
1
+ # {{projectName}}
2
+
3
+ An Esmx project with Vue and Server-Side Rendering.
4
+
5
+ ## 📦 Tech Stack
6
+
7
+ - **Framework**: [Esmx](https://esmnext.com) - Next generation micro-frontend framework based on native ESM
8
+ - **UI Framework**: Vue
9
+ - **Build Tool**: Rspack
10
+ - **Type Checking**: TypeScript
11
+ - **Rendering Mode**: Server-Side Rendering (SSR)
12
+
13
+ ## 🚀 Quick Start
14
+
15
+ ### Install Dependencies
16
+
17
+ ```bash
18
+ {{installCommand}}
19
+ ```
20
+
21
+ ### Development Environment
22
+
23
+ ```bash
24
+ {{devCommand}}
25
+ ```
26
+
27
+ Visit http://localhost:3000 to see the development environment.
28
+
29
+ ### Production Build
30
+
31
+ ```bash
32
+ {{buildCommand}}
33
+ ```
34
+
35
+ ### Start Production Server
36
+
37
+ ```bash
38
+ {{startCommand}}
39
+ ```
40
+
41
+ ### Type Generation
42
+
43
+ ```bash
44
+ {{buildTypeCommand}}
45
+ ```
46
+
47
+ ### Type Checking
48
+
49
+ ```bash
50
+ {{lintTypeCommand}}
51
+ ```
52
+
53
+ ## 📁 Project Structure
54
+
55
+ ```
56
+ {{projectName}}/
57
+ ├── src/
58
+ │ ├── app.vue # Main application component with Esmx and Vue logos
59
+ │ ├── components/ # UI components
60
+ │ │ └── hello-world.vue # Example component with counter functionality
61
+ │ ├── create-app.ts # Vue instance creation
62
+ │ ├── entry.client.ts # Client-side entry
63
+ │ ├── entry.node.ts # Node.js environment entry point
64
+ │ └── entry.server.ts # Server-side rendering functions
65
+ ├── package.json
66
+ ├── tsconfig.json
67
+ └── README.md
68
+ ```
69
+
70
+ ## 🔧 Configuration Details
71
+
72
+ - `entry.client.ts` - Responsible for client-side interaction and dynamic updates
73
+ - `entry.node.ts` - Handles server-side rendering and development server configuration
74
+ - `entry.server.ts` - Manages server-side rendering process and HTML generation
75
+
76
+ ## 📚 Additional Resources
77
+
78
+ - [Esmx Official Documentation](https://esmnext.com)
79
+ - [Vue Documentation](https://vuejs.org)
80
+ - [TypeScript Documentation](https://www.typescriptlang.org)
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "1.0.0",
4
+ "description": "Vue Server-Side Rendering framework",
5
+ "type": "module",
6
+ "private": true,
7
+ "scripts": {
8
+ "dev": "esmx dev",
9
+ "build": "esmx build",
10
+ "preview": "esmx preview",
11
+ "start": "esmx start",
12
+ "lint:type": "vue-tsc --noEmit",
13
+ "build:type": "vue-tsc --declaration --emitDeclarationOnly --noEmit false --outDir dist/src && tsc-alias -p tsconfig.json --outDir dist/src"
14
+ },
15
+ "dependencies": {
16
+ "@esmx/core": "{{esmxVersion}}"
17
+ },
18
+ "devDependencies": {
19
+ "tsc-alias": "^1.8.16",
20
+ "@esmx/rspack-vue": "{{esmxVersion}}",
21
+ "@types/node": "^24.0.0",
22
+ "vue": "3.5.18",
23
+ "@vue/server-renderer": "3.5.18",
24
+ "typescript": "5.8.3",
25
+ "vue-tsc": "^3.0.1"
26
+ }
27
+ }
@@ -0,0 +1,127 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+ import HelloWorld from './components/hello-world.vue';
4
+
5
+ const title = ref<string>('Vue SSR Demo');
6
+ </script>
7
+
8
+ <template>
9
+ <div class="container">
10
+ <div class="logo-container">
11
+ <a href="https://www.esmnext.com" target="_blank" class="logo-link">
12
+ <div class="logo-wrapper esmx">
13
+ <img src="https://www.esmnext.com/logo.svg" class="logo" alt="Esmx logo" />
14
+ </div>
15
+ </a>
16
+ <a href="https://vuejs.org/" target="_blank" class="logo-link">
17
+ <div class="logo-wrapper vue">
18
+ <img src="https://vuejs.org/logo.svg" class="logo" alt="Vue logo" />
19
+ </div>
20
+ </a>
21
+ </div>
22
+ <HelloWorld :msg="title" />
23
+ </div>
24
+ </template>
25
+
26
+ <style>
27
+ :root {
28
+ --esmx-primary: #001137;
29
+ --esmx-secondary: #273498;
30
+ --esmx-accent: #0074C2;
31
+ --esmx-light: #00ABE7;
32
+ --esmx-sun-core: #FFA000;
33
+ --esmx-sun-rays: #FFC107;
34
+ --vue-color: #42b883;
35
+ --vue-dark: #33a06f;
36
+ --border-color: rgba(0, 17, 55, 0.12);
37
+ --shadow-color: rgba(0, 17, 55, 0.05);
38
+ --text-primary: #213547;
39
+ --text-secondary: #666;
40
+ --bg-card: #fcfcfc;
41
+ --bg-hover: rgba(255, 250, 240, 0.8);
42
+ --font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
43
+ }
44
+
45
+ body {
46
+ margin: 0;
47
+ font-family: var(--font-family);
48
+ color: var(--text-primary);
49
+ background-color: white;
50
+ line-height: 1.6;
51
+ -webkit-font-smoothing: antialiased;
52
+ -moz-osx-font-smoothing: grayscale;
53
+ }
54
+ </style>
55
+
56
+ <style scoped>
57
+ .container {
58
+ max-width: 1280px;
59
+ margin: 0 auto;
60
+ padding: 2rem;
61
+ text-align: center;
62
+ font-family: var(--font-family);
63
+ }
64
+
65
+ .logo-container {
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ gap: 3.5rem;
70
+ margin-bottom: 3rem;
71
+ }
72
+
73
+ .logo-link {
74
+ text-decoration: none;
75
+ position: relative;
76
+ }
77
+
78
+ .logo-wrapper {
79
+ display: flex;
80
+ justify-content: center;
81
+ align-items: center;
82
+ width: 6.5em;
83
+ height: 6.5em;
84
+ border-radius: 12px;
85
+ background-color: var(--bg-card);
86
+ padding: 1em;
87
+ box-shadow: 0 2px 12px var(--shadow-color);
88
+ border: 1px solid var(--border-color);
89
+ transition: all 0.3s ease;
90
+ }
91
+
92
+ .logo-wrapper:hover {
93
+ transform: translateY(-5px);
94
+ box-shadow: 0 5px 15px var(--shadow-color);
95
+ }
96
+
97
+ .logo {
98
+ height: 100%;
99
+ width: auto;
100
+ transition: transform 0.3s ease;
101
+ }
102
+
103
+ .logo-wrapper:hover .logo {
104
+ transform: scale(1.1);
105
+ }
106
+
107
+ .logo-wrapper.esmx:hover {
108
+ background-color: rgba(255, 192, 7, 0.1);
109
+ border-color: var(--esmx-sun-rays);
110
+ }
111
+
112
+ .logo-wrapper.vue:hover {
113
+ background-color: rgba(66, 184, 131, 0.1);
114
+ border-color: var(--vue-color);
115
+ }
116
+
117
+ @media (max-width: 768px) {
118
+ .logo-container {
119
+ gap: 2rem;
120
+ }
121
+
122
+ .logo-wrapper {
123
+ width: 5em;
124
+ height: 5em;
125
+ }
126
+ }
127
+ </style>
@@ -0,0 +1,77 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+
4
+ defineProps({
5
+ msg: {
6
+ type: String
7
+ }
8
+ });
9
+ const count = ref<number>(0);
10
+ </script>
11
+
12
+ <template>
13
+ <div>
14
+ <h1>{{ msg }}</h1>
15
+
16
+ <div class="card">
17
+ <button type="button" @click="count++">Counter: {{ count }}</button>
18
+ <p>
19
+ Edit
20
+ <code>components/HelloWorld.vue</code> to test HMR
21
+ </p>
22
+ </div>
23
+
24
+ <p>Experience Vue with server-side rendering powered by Esmx framework</p>
25
+ </div>
26
+ </template>
27
+
28
+ <style scoped>
29
+ .card {
30
+ padding: 2em;
31
+ border-radius: 12px;
32
+ margin: 2.5em 0;
33
+ background-color: var(--bg-card);
34
+ }
35
+
36
+ button {
37
+ border-radius: 8px;
38
+ border: 1px solid transparent;
39
+ padding: 0.6em 1.2em;
40
+ font-size: 1em;
41
+ font-weight: 600;
42
+ font-family: inherit;
43
+ background-color: var(--esmx-sun-rays);
44
+ color: #fff;
45
+ cursor: pointer;
46
+ margin-bottom: 1em;
47
+ transition: all 0.25s ease;
48
+ }
49
+
50
+ button:hover {
51
+ background-color: var(--esmx-sun-core);
52
+ transform: translateY(-1px);
53
+ box-shadow: 0 4px 8px rgba(255, 160, 0, 0.25);
54
+ }
55
+
56
+ h1 {
57
+ font-size: 3.2em;
58
+ line-height: 1.1;
59
+ margin-bottom: 1em;
60
+ color: var(--esmx-primary);
61
+ font-weight: 700;
62
+ }
63
+
64
+ p {
65
+ line-height: 1.6;
66
+ margin: 0.5em 0;
67
+ color: var(--text-primary);
68
+ }
69
+
70
+ code {
71
+ background-color: rgba(0, 116, 194, 0.1);
72
+ padding: 0.2em 0.4em;
73
+ border-radius: 4px;
74
+ font-family: monospace;
75
+ font-size: 0.9em;
76
+ }
77
+ </style>
@@ -0,0 +1,9 @@
1
+ import { createApp } from 'vue';
2
+ import App from './app.vue';
3
+
4
+ export function createVueApp() {
5
+ const app = createApp(App);
6
+ return {
7
+ app
8
+ };
9
+ }
@@ -0,0 +1,5 @@
1
+ import { createVueApp } from './create-app';
2
+
3
+ const { app } = createVueApp();
4
+
5
+ app.mount('#app');
@@ -0,0 +1,37 @@
1
+ import http from 'node:http';
2
+ import type { EsmxOptions } from '@esmx/core';
3
+
4
+ export default {
5
+ modules: {
6
+ exports: ['npm:vue']
7
+ },
8
+ async devApp(esmx) {
9
+ return import('@esmx/rspack-vue').then((m) =>
10
+ m.createRspackVue3App(esmx, {
11
+ chain(context) {
12
+ // Custom Rspack configuration
13
+ }
14
+ })
15
+ );
16
+ },
17
+
18
+ async postBuild(esmx) {
19
+ const rc = await esmx.render();
20
+ esmx.writeSync(esmx.resolvePath('dist/client', 'index.html'), rc.html);
21
+ },
22
+
23
+ async server(esmx) {
24
+ const server = http.createServer((req, res) => {
25
+ esmx.middleware(req, res, async () => {
26
+ const rc = await esmx.render({
27
+ params: { url: req.url }
28
+ });
29
+ res.end(rc.html);
30
+ });
31
+ });
32
+
33
+ server.listen(3000, () => {
34
+ console.log('Server started: http://localhost:3000');
35
+ });
36
+ }
37
+ } satisfies EsmxOptions;
@@ -0,0 +1,30 @@
1
+ import type { RenderContext } from '@esmx/core';
2
+ import { renderToString } from '@vue/server-renderer';
3
+ import { createVueApp } from './create-app';
4
+
5
+ export default async (rc: RenderContext) => {
6
+ const { app } = createVueApp();
7
+ const html = await renderToString(app);
8
+ await rc.commit();
9
+
10
+ rc.html = `<!DOCTYPE html>
11
+ <html lang="en">
12
+ <head>
13
+ <meta charset="UTF-8">
14
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
15
+ <meta name="description" content="Vue with Server-Side Rendering powered by Esmx framework">
16
+ <meta name="keywords" content="Vue, SSR, Server-Side Rendering, Esmx, Vue.js, JavaScript, TypeScript, Rspack">
17
+ <link rel="icon" href="https://www.esmnext.com/logo.svg" type="image/svg+xml">
18
+ ${rc.preload()}
19
+ <title>Vue SSR Demo | Powered by Esmx</title>
20
+ ${rc.css()}
21
+ </head>
22
+ <body>
23
+ <div id="app">${html}</div>
24
+ ${rc.importmap()}
25
+ ${rc.moduleEntry()}
26
+ ${rc.modulePreload()}
27
+ </body>
28
+ </html>
29
+ `;
30
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "ESNext",
4
+ "moduleResolution": "node",
5
+ "isolatedModules": true,
6
+ "resolveJsonModule": true,
7
+
8
+ "target": "ESNext",
9
+ "lib": ["ESNext", "DOM"],
10
+
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "types": ["@types/node"],
14
+
15
+ "experimentalDecorators": true,
16
+ "allowSyntheticDefaultImports": true,
17
+
18
+ "baseUrl": ".",
19
+ "paths": {
20
+ "{{projectName}}/src/*": ["./src/*"],
21
+ "{{projectName}}/*": ["./*"]
22
+ }
23
+ },
24
+ "include": ["src"],
25
+ "exclude": ["dist", "node_modules"]
26
+ }
@@ -2,6 +2,9 @@ import http from 'node:http';
2
2
  import type { EsmxOptions } from '@esmx/core';
3
3
 
4
4
  export default {
5
+ modules: {
6
+ exports: ['npm:vue']
7
+ },
5
8
  async devApp(esmx) {
6
9
  return import('@esmx/rspack-vue').then((m) =>
7
10
  m.createRspackVue2App(esmx, {
@@ -2,6 +2,9 @@ import http from 'node:http';
2
2
  import type { EsmxOptions } from '@esmx/core';
3
3
 
4
4
  export default {
5
+ modules: {
6
+ exports: ['npm:vue']
7
+ },
5
8
  async devApp(esmx) {
6
9
  return import('@esmx/rspack-vue').then((m) =>
7
10
  m.createRspackVue2App(esmx, {