feat: add basic-jsx and basic-template examples
- basic-jsx: Counter + Clock with defineComponent() + JSX - basic-template: Counter + Clock with .vue SFC + <template> - Both demonstrate HMR via vue-tui dev - Fix vite-plugin: strip build.lib and external config for bundledDev, add node builtins resolveId to prevent browser-external shimming - Remove old hmr-demo example (superseded by basic-template) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "@vue-tui/example-basic-jsx",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vue-tui dev",
|
||||
"build": "vite build",
|
||||
"start": "vite build && node dist/game.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue-tui/cli": "workspace:*",
|
||||
"@vue-tui/runtime": "workspace:*",
|
||||
"vue": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "catalog:",
|
||||
"@vitejs/plugin-vue-jsx": "^5",
|
||||
"vite": "catalog:"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { shallowRef, defineComponent } from "vue";
|
||||
import { Box, Text, useInput } from "@vue-tui/runtime";
|
||||
import Counter from "./Counter";
|
||||
import Clock from "./Clock";
|
||||
|
||||
export default defineComponent(() => {
|
||||
const showClock = shallowRef(true);
|
||||
|
||||
useInput((input) => {
|
||||
if (input === "c") showClock.value = !showClock.value;
|
||||
if (input === "q") process.exit(0);
|
||||
});
|
||||
|
||||
return () => (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
<Text bold color="cyan">
|
||||
vue-tui basic (JSX)
|
||||
</Text>
|
||||
<Text dimColor>Try editing Counter.tsx or App.tsx</Text>
|
||||
<Text dimColor>Press c=toggle clock, q=quit</Text>
|
||||
<Text> </Text>
|
||||
<Counter />
|
||||
{showClock.value && <Clock />}
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { shallowRef, onMounted, onUnmounted, defineComponent } from "vue";
|
||||
import { Box, Text } from "@vue-tui/runtime";
|
||||
|
||||
export default defineComponent(() => {
|
||||
const time = shallowRef(new Date().toLocaleTimeString());
|
||||
let timer: ReturnType<typeof setInterval>;
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
time.value = new Date().toLocaleTimeString();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
});
|
||||
|
||||
return () => (
|
||||
<Box>
|
||||
<Text>Clock: </Text>
|
||||
<Text bold color="yellow">
|
||||
{time.value}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
import { shallowRef, defineComponent } from "vue";
|
||||
import { Box, Text, useInput } from "@vue-tui/runtime";
|
||||
|
||||
export default defineComponent(() => {
|
||||
const count = shallowRef(0);
|
||||
|
||||
useInput((input) => {
|
||||
if (input === "+") count.value++;
|
||||
if (input === "-") count.value--;
|
||||
});
|
||||
|
||||
return () => (
|
||||
<Box>
|
||||
<Text>Count: </Text>
|
||||
<Text bold color="green">
|
||||
{count.value}
|
||||
</Text>
|
||||
<Text dimColor> (+/- to change)</Text>
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
import { createApp } from "@vue-tui/runtime";
|
||||
import App from "./App";
|
||||
|
||||
createApp(App).mount();
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "vue",
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx"]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { defineConfig } from "vite";
|
||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const here = fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vueJsx()],
|
||||
build: {
|
||||
target: "node22",
|
||||
outDir: "dist",
|
||||
emptyOutDir: true,
|
||||
minify: false,
|
||||
lib: {
|
||||
entry: `${here}src/main.tsx`,
|
||||
formats: ["es"],
|
||||
fileName: () => "game.mjs",
|
||||
},
|
||||
rollupOptions: {
|
||||
external: (id) => !id.startsWith(".") && !id.startsWith("/") && !id.startsWith("\0"),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@vue-tui/example-hmr-demo",
|
||||
"name": "@vue-tui/example-basic-template",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { shallowRef, defineComponent } from "vue";
|
||||
import { Box, Text, useInput } from "@vue-tui/runtime";
|
||||
import Counter from "./Counter.vue";
|
||||
import Clock from "./Clock.vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: { Box, Text, Counter, Clock },
|
||||
setup() {
|
||||
const showClock = shallowRef(true);
|
||||
|
||||
useInput((input) => {
|
||||
if (input === "c") showClock.value = !showClock.value;
|
||||
if (input === "q") process.exit(0);
|
||||
});
|
||||
|
||||
return { showClock };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Box flexDirection="column" :paddingX="1">
|
||||
<Text bold color="cyan">vue-tui basic (template)</Text>
|
||||
<Text dimColor>Try editing Counter.vue or App.vue</Text>
|
||||
<Text dimColor>Press c=toggle clock, q=quit</Text>
|
||||
<Text> </Text>
|
||||
<Counter />
|
||||
<Clock v-if="showClock" />
|
||||
</Box>
|
||||
</template>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { shallowRef, onMounted, onUnmounted, defineComponent } from "vue";
|
||||
import { Box, Text } from "@vue-tui/runtime";
|
||||
|
||||
export default defineComponent({
|
||||
components: { Box, Text },
|
||||
setup() {
|
||||
const time = shallowRef(new Date().toLocaleTimeString());
|
||||
let timer: ReturnType<typeof setInterval>;
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
time.value = new Date().toLocaleTimeString();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
});
|
||||
|
||||
return { time };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Box>
|
||||
<Text>Clock: </Text>
|
||||
<Text bold color="yellow">{{ time }}</Text>
|
||||
</Box>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { shallowRef, defineComponent } from "vue";
|
||||
import { Box, Text, useInput } from "@vue-tui/runtime";
|
||||
|
||||
export default defineComponent({
|
||||
components: { Box, Text },
|
||||
setup() {
|
||||
const count = shallowRef(0);
|
||||
|
||||
useInput((input) => {
|
||||
if (input === "+") count.value++;
|
||||
if (input === "-") count.value--;
|
||||
});
|
||||
|
||||
return { count };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Box>
|
||||
<Text>Count: </Text>
|
||||
<Text bold color="green">{{ count }}</Text>
|
||||
<Text dimColor> (+/- to change)</Text>
|
||||
</Box>
|
||||
</template>
|
||||
@@ -1,27 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { shallowRef, onMounted, onUnmounted } from "vue";
|
||||
import { Box, Text, useInput } from "@vue-tui/runtime";
|
||||
import Counter from "./Counter.vue";
|
||||
import Clock from "./Clock.vue";
|
||||
|
||||
const title = "HMR Demo";
|
||||
const hint = "Try editing Counter.vue (HMR) or App.vue (reload)";
|
||||
|
||||
const showClock = shallowRef(true);
|
||||
|
||||
useInput((input) => {
|
||||
if (input === "c") showClock.value = !showClock.value;
|
||||
if (input === "q") process.exit(0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Box flexDirection="column" :paddingX="1">
|
||||
<Text bold color="cyan">{{ title }}</Text>
|
||||
<Text dimColor>{{ hint }}</Text>
|
||||
<Text dimColor>Press c=toggle clock, q=quit</Text>
|
||||
<Text> </Text>
|
||||
<Counter />
|
||||
<Clock v-if="showClock" />
|
||||
</Box>
|
||||
</template>
|
||||
@@ -1,24 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { shallowRef, onMounted, onUnmounted } from "vue";
|
||||
import { Box, Text } from "@vue-tui/runtime";
|
||||
|
||||
const time = shallowRef(new Date().toLocaleTimeString());
|
||||
let timer: ReturnType<typeof setInterval>;
|
||||
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
time.value = new Date().toLocaleTimeString();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Box>
|
||||
<Text>Clock: </Text>
|
||||
<Text bold color="yellow">{{ time }}</Text>
|
||||
</Box>
|
||||
</template>
|
||||
@@ -1,19 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from "vue";
|
||||
import { Box, Text, useInput } from "@vue-tui/runtime";
|
||||
|
||||
const count = shallowRef(0);
|
||||
|
||||
useInput((input) => {
|
||||
if (input === "+") count.value++;
|
||||
if (input === "-") count.value--;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Box>
|
||||
<Text>Count: </Text>
|
||||
<Text bold color="green">{{ count }}</Text>
|
||||
<Text dimColor> (+/- to change)</Text>
|
||||
</Box>
|
||||
</template>
|
||||
@@ -1,29 +1,48 @@
|
||||
import type { Plugin } from "vite";
|
||||
import { builtinModules } from "node:module";
|
||||
|
||||
export interface VueTuiDevPluginOptions {
|
||||
entry?: string;
|
||||
}
|
||||
|
||||
export function vueTuiDevPlugin(options?: VueTuiDevPluginOptions): Plugin {
|
||||
return {
|
||||
name: "vue-tui:dev",
|
||||
config() {
|
||||
return {
|
||||
experimental: { bundledDev: true },
|
||||
build: {
|
||||
modulePreload: false,
|
||||
...(options?.entry ? { lib: { entry: options.entry } } : {}),
|
||||
},
|
||||
define: {
|
||||
__VUE_TUI_DEV__: "true",
|
||||
},
|
||||
resolve: {
|
||||
conditions: ["node"],
|
||||
},
|
||||
server: {
|
||||
strictPort: true,
|
||||
},
|
||||
};
|
||||
const nodeBuiltins = new Set([...builtinModules, ...builtinModules.map((m) => `node:${m}`)]);
|
||||
|
||||
export function vueTuiDevPlugin(_options?: VueTuiDevPluginOptions): Plugin[] {
|
||||
return [
|
||||
{
|
||||
name: "vue-tui:node-builtins",
|
||||
enforce: "pre",
|
||||
resolveId(id) {
|
||||
if (nodeBuiltins.has(id)) {
|
||||
return { id: id.startsWith("node:") ? id : `node:${id}`, external: true };
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
{
|
||||
name: "vue-tui:dev",
|
||||
config(config) {
|
||||
// bundledDev uses index.html as entry, not build.lib
|
||||
if (config.build?.lib) {
|
||||
config.build.lib = undefined;
|
||||
}
|
||||
// bundledDev bundles everything — strip user's external config
|
||||
if (config.build?.rollupOptions) {
|
||||
config.build.rollupOptions.external = undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
experimental: { bundledDev: true },
|
||||
build: {
|
||||
modulePreload: false,
|
||||
},
|
||||
define: {
|
||||
__VUE_TUI_DEV__: "true",
|
||||
},
|
||||
server: {
|
||||
strictPort: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
Generated
+56
@@ -62,6 +62,50 @@ importers:
|
||||
specifier: npm:@voidzero-dev/vite-plus-core@latest
|
||||
version: '@voidzero-dev/vite-plus-core@0.1.22(@types/node@24.12.4)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)'
|
||||
|
||||
examples/basic-jsx:
|
||||
dependencies:
|
||||
'@vue-tui/cli':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/cli
|
||||
'@vue-tui/runtime':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/runtime
|
||||
vue:
|
||||
specifier: ^3.4.0
|
||||
version: 3.5.34(typescript@6.0.3)
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: 'catalog:'
|
||||
version: 24.12.4
|
||||
'@vitejs/plugin-vue-jsx':
|
||||
specifier: ^5
|
||||
version: 5.1.5(@voidzero-dev/vite-plus-core@0.1.22(@types/node@24.12.4)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vue@3.5.34(typescript@6.0.3))
|
||||
vite:
|
||||
specifier: npm:@voidzero-dev/vite-plus-core@latest
|
||||
version: '@voidzero-dev/vite-plus-core@0.1.22(@types/node@24.12.4)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)'
|
||||
|
||||
examples/basic-template:
|
||||
dependencies:
|
||||
'@vue-tui/cli':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/cli
|
||||
'@vue-tui/runtime':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/runtime
|
||||
vue:
|
||||
specifier: ^3.4.0
|
||||
version: 3.5.34(typescript@6.0.3)
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: 'catalog:'
|
||||
version: 24.12.4
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^6
|
||||
version: 6.0.7(@voidzero-dev/vite-plus-core@0.1.22(@types/node@24.12.4)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vue@3.5.34(typescript@6.0.3))
|
||||
vite:
|
||||
specifier: npm:@voidzero-dev/vite-plus-core@latest
|
||||
version: '@voidzero-dev/vite-plus-core@0.1.22(@types/node@24.12.4)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)'
|
||||
|
||||
examples/flappy-bird:
|
||||
dependencies:
|
||||
'@vue-tui/runtime':
|
||||
@@ -2098,6 +2142,18 @@ snapshots:
|
||||
'@typescript/native-preview-win32-arm64': 7.0.0-dev.20260509.2
|
||||
'@typescript/native-preview-win32-x64': 7.0.0-dev.20260509.2
|
||||
|
||||
'@vitejs/plugin-vue-jsx@5.1.5(@voidzero-dev/vite-plus-core@0.1.22(@types/node@24.12.4)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0))(vue@3.5.34(typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0)
|
||||
'@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0)
|
||||
'@rolldown/pluginutils': 1.0.1
|
||||
'@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.0)
|
||||
vite: '@voidzero-dev/vite-plus-core@0.1.22(@types/node@24.12.4)(jiti@2.7.0)(typescript@6.0.3)(yaml@2.9.0)'
|
||||
vue: 3.5.34(typescript@6.0.3)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitejs/plugin-vue-jsx@5.1.5(vite@8.0.13(@types/node@25.8.0)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.34(typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
|
||||
Reference in New Issue
Block a user