@harperfast/template-vue-ts-studio 1.7.4 → 1.8.2

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.
@@ -1617,59 +1617,78 @@ Instructions for the agent to follow when serving web content from Harper.
1617
1617
 
1618
1618
  #### When to Use
1619
1619
 
1620
- Use this skill when you need to serve a frontend (HTML, CSS, JS, or a React app) directly from your Harper instance.
1620
+ Use this skill when you need to serve a frontend (HTML, CSS, JS, or a React/Vue app) directly from your Harper instance — either plain static files or an integrated Vite app with hot module replacement (HMR) in development and a real production build when deployed.
1621
1621
 
1622
1622
  #### How It Works
1623
1623
 
1624
- 1. **Choose a Method**: Decide between the simple Static Plugin or the integrated Vite Plugin.
1625
- 2. **Option A: Static Plugin (Simple)**:
1626
- - Add to `config.yaml`:
1627
- ```yaml
1628
- static:
1629
- files: 'web/*'
1630
- ```
1631
- - Place files in a `web/` folder in the project root.
1632
- - Files are served at the root URL (e.g., `http://localhost:9926/index.html`).
1633
- 3. **Option B: Vite Plugin (Advanced/Development)**:
1634
- - Add to `config.yaml`:
1635
- ```yaml
1636
- '@harperfast/vite-plugin':
1637
- package: '@harperfast/vite-plugin'
1638
- ```
1639
- - Ensure `vite.config.ts` and `index.html` are in the project root.
1624
+ There are two building blocks. Harper's built-in `static` plugin **serves** files; the `@harperfast/vite` plugin **builds** (and, for SSR, **renders**) a Vite app. For a Vite app they work **together** — the plugin builds into a directory and `static` serves that same directory.
1640
1625
 
1641
- ```javascript
1642
- import vue from '@vitejs/plugin-vue';
1643
- import path from 'node:path';
1644
- import { defineConfig } from 'vite';
1645
-
1646
- // https://vite.dev/config/
1647
- export default defineConfig({
1648
- plugins: [vue()],
1649
- resolve: {
1650
- alias: {
1651
- '@': path.resolve(import.meta.dirname, './src'),
1652
- },
1653
- },
1654
- build: {
1655
- outDir: 'web',
1656
- emptyOutDir: true,
1657
- rolldownOptions: {
1658
- external: ['**/*.test.*', '**/*.spec.*'],
1659
- },
1660
- },
1661
- });
1662
- ```
1626
+ ##### Option A: Static plugin only (simple, pre-built assets)
1663
1627
 
1664
- - Install dependencies: `npm install --save-dev vite @harperfast/vite-plugin`.
1665
- - Then `harper run .` will start up Harper and Vite with HMR. Vite does _not_ need to be executed separately.
1628
+ For a plain static site or already-built assets, use `static` on its own:
1666
1629
 
1667
- 4. **Deploy for Production**: For Vite apps, use a build script to generate static files into a `web/` folder and deploy them using the static handler pattern. For example, these scripts in a package.json can perform the necessary steps:
1668
- ```json
1669
- "build": "vite build",
1670
- "deploy": "rm -Rf deploy && npm run build && mkdir deploy && mv web deploy/ && cp -R deploy-template/* deploy/ && cp -R schemas resources deploy/ && (cd deploy && harper deploy_component . project=web restart=rolling replicated=true) && rm -Rf deploy",
1671
- ```
1672
- Then in production, the "Static Plugin" option will performantly and securely serve your assets. `npm create harper@latest` scaffolds all of this for you.
1630
+ ```yaml
1631
+ static:
1632
+ files: 'web/*'
1633
+ ```
1634
+
1635
+ - Place files in a `web/` folder in the project root; they are served from the root URL (e.g. `http://localhost:9926/index.html`).
1636
+ - Static files are matched first; if none matches, Harper falls through to your resource and table APIs.
1637
+
1638
+ ##### Option B: Vite plugin + static plugin (integrated Vite app)
1639
+
1640
+ > **Renamed in v1:** the plugin was previously `@harperfast/vite-plugin`. From `1.0.0` on it is **`@harperfast/vite`** (same key and `package`). It now pairs with the `static` plugin instead of building into `web/` itself.
1641
+
1642
+ `@harperfast/vite` **builds** your app — in `harper dev` it runs Vite in middleware mode with HMR; in `harper run` it runs `vite build` and rebuilds when watched files change (and renders HTML for SSR). The `static` plugin **serves** the built output. Point both at the same directory (`output`, default `dist`) — that shared directory is the only contract between them.
1643
+
1644
+ **SPA `config.yaml`** — list the plugin first so its dev server wins in `harper dev`; `notFound` + `fallthrough: false` makes client-side routing work:
1645
+
1646
+ ```yaml
1647
+ '@harperfast/vite':
1648
+ package: '@harperfast/vite'
1649
+ files: 'src/**/*'
1650
+ output: 'dist'
1651
+
1652
+ static:
1653
+ files: 'dist/**'
1654
+ notFound:
1655
+ file: 'index.html'
1656
+ statusCode: 200
1657
+ fallthrough: false
1658
+ ```
1659
+
1660
+ **SSR `config.yaml`** — add an `ssr` entry so the plugin renders `index.html`, and set `index: false` on `static` so it serves assets only:
1661
+
1662
+ ```yaml
1663
+ '@harperfast/vite':
1664
+ package: '@harperfast/vite'
1665
+ files: 'src/**/*'
1666
+ output: 'dist'
1667
+ ssr: 'src/entry-server.tsx'
1668
+
1669
+ static:
1670
+ files: 'dist/**'
1671
+ index: false
1672
+ ```
1673
+
1674
+ - Install dependencies: `npm install --save-dev vite @harperfast/vite @vitejs/plugin-react` (swap in your framework's Vite plugin, e.g. `@vitejs/plugin-vue`).
1675
+ - Then `harper dev .` runs the app with HMR and `harper run .` runs the production build. Vite does _not_ need to be executed separately.
1676
+
1677
+ #### Deploying to Production
1678
+
1679
+ Because `@harperfast/vite` builds on the node and `static` serves the output, deploy the component as-is — no manual build-and-move step is needed:
1680
+
1681
+ ```json
1682
+ {
1683
+ "scripts": {
1684
+ "dev": "harper dev .",
1685
+ "start": "harper run .",
1686
+ "deploy": "harper deploy_component . restart=true replicated=true"
1687
+ }
1688
+ }
1689
+ ```
1690
+
1691
+ On deploy the plugin runs `vite build` at startup (and rebuilds when `files` change) while `static` serves the result. If you prefer to build in CI, commit the build output, point `static` at it, and omit `files` so the plugin stays idle while `static` serves the prebuilt assets. Either way, `npm create harper@latest` scaffolds a working setup for you.
1673
1692
 
1674
1693
  ### 4.5 Harper Logging
1675
1694
 
@@ -11,56 +11,75 @@ Instructions for the agent to follow when serving web content from Harper.
11
11
 
12
12
  ## When to Use
13
13
 
14
- Use this skill when you need to serve a frontend (HTML, CSS, JS, or a React app) directly from your Harper instance.
14
+ Use this skill when you need to serve a frontend (HTML, CSS, JS, or a React/Vue app) directly from your Harper instance — either plain static files or an integrated Vite app with hot module replacement (HMR) in development and a real production build when deployed.
15
15
 
16
16
  ## How It Works
17
17
 
18
- 1. **Choose a Method**: Decide between the simple Static Plugin or the integrated Vite Plugin.
19
- 2. **Option A: Static Plugin (Simple)**:
20
- - Add to `config.yaml`:
21
- ```yaml
22
- static:
23
- files: 'web/*'
24
- ```
25
- - Place files in a `web/` folder in the project root.
26
- - Files are served at the root URL (e.g., `http://localhost:9926/index.html`).
27
- 3. **Option B: Vite Plugin (Advanced/Development)**:
28
- - Add to `config.yaml`:
29
- ```yaml
30
- '@harperfast/vite-plugin':
31
- package: '@harperfast/vite-plugin'
32
- ```
33
- - Ensure `vite.config.ts` and `index.html` are in the project root.
34
-
35
- ```javascript
36
- import vue from '@vitejs/plugin-vue';
37
- import path from 'node:path';
38
- import { defineConfig } from 'vite';
39
-
40
- // https://vite.dev/config/
41
- export default defineConfig({
42
- plugins: [vue()],
43
- resolve: {
44
- alias: {
45
- '@': path.resolve(import.meta.dirname, './src'),
46
- },
47
- },
48
- build: {
49
- outDir: 'web',
50
- emptyOutDir: true,
51
- rolldownOptions: {
52
- external: ['**/*.test.*', '**/*.spec.*'],
53
- },
54
- },
55
- });
56
- ```
57
-
58
- - Install dependencies: `npm install --save-dev vite @harperfast/vite-plugin`.
59
- - Then `harper run .` will start up Harper and Vite with HMR. Vite does _not_ need to be executed separately.
60
-
61
- 4. **Deploy for Production**: For Vite apps, use a build script to generate static files into a `web/` folder and deploy them using the static handler pattern. For example, these scripts in a package.json can perform the necessary steps:
62
- ```json
63
- "build": "vite build",
64
- "deploy": "rm -Rf deploy && npm run build && mkdir deploy && mv web deploy/ && cp -R deploy-template/* deploy/ && cp -R schemas resources deploy/ && (cd deploy && harper deploy_component . project=web restart=rolling replicated=true) && rm -Rf deploy",
65
- ```
66
- Then in production, the "Static Plugin" option will performantly and securely serve your assets. `npm create harper@latest` scaffolds all of this for you.
18
+ There are two building blocks. Harper's built-in `static` plugin **serves** files; the `@harperfast/vite` plugin **builds** (and, for SSR, **renders**) a Vite app. For a Vite app they work **together** — the plugin builds into a directory and `static` serves that same directory.
19
+
20
+ ### Option A: Static plugin only (simple, pre-built assets)
21
+
22
+ For a plain static site or already-built assets, use `static` on its own:
23
+
24
+ ```yaml
25
+ static:
26
+ files: 'web/*'
27
+ ```
28
+
29
+ - Place files in a `web/` folder in the project root; they are served from the root URL (e.g. `http://localhost:9926/index.html`).
30
+ - Static files are matched first; if none matches, Harper falls through to your resource and table APIs.
31
+
32
+ ### Option B: Vite plugin + static plugin (integrated Vite app)
33
+
34
+ > **Renamed in v1:** the plugin was previously `@harperfast/vite-plugin`. From `1.0.0` on it is **`@harperfast/vite`** (same key and `package`). It now pairs with the `static` plugin instead of building into `web/` itself.
35
+
36
+ `@harperfast/vite` **builds** your app — in `harper dev` it runs Vite in middleware mode with HMR; in `harper run` it runs `vite build` and rebuilds when watched files change (and renders HTML for SSR). The `static` plugin **serves** the built output. Point both at the same directory (`output`, default `dist`) — that shared directory is the only contract between them.
37
+
38
+ **SPA `config.yaml`** list the plugin first so its dev server wins in `harper dev`; `notFound` + `fallthrough: false` makes client-side routing work:
39
+
40
+ ```yaml
41
+ '@harperfast/vite':
42
+ package: '@harperfast/vite'
43
+ files: 'src/**/*'
44
+ output: 'dist'
45
+
46
+ static:
47
+ files: 'dist/**'
48
+ notFound:
49
+ file: 'index.html'
50
+ statusCode: 200
51
+ fallthrough: false
52
+ ```
53
+
54
+ **SSR `config.yaml`** — add an `ssr` entry so the plugin renders `index.html`, and set `index: false` on `static` so it serves assets only:
55
+
56
+ ```yaml
57
+ '@harperfast/vite':
58
+ package: '@harperfast/vite'
59
+ files: 'src/**/*'
60
+ output: 'dist'
61
+ ssr: 'src/entry-server.tsx'
62
+
63
+ static:
64
+ files: 'dist/**'
65
+ index: false
66
+ ```
67
+
68
+ - Install dependencies: `npm install --save-dev vite @harperfast/vite @vitejs/plugin-react` (swap in your framework's Vite plugin, e.g. `@vitejs/plugin-vue`).
69
+ - Then `harper dev .` runs the app with HMR and `harper run .` runs the production build. Vite does _not_ need to be executed separately.
70
+
71
+ ## Deploying to Production
72
+
73
+ Because `@harperfast/vite` builds on the node and `static` serves the output, deploy the component as-is — no manual build-and-move step is needed:
74
+
75
+ ```json
76
+ {
77
+ "scripts": {
78
+ "dev": "harper dev .",
79
+ "start": "harper run .",
80
+ "deploy": "harper deploy_component . restart=true replicated=true"
81
+ }
82
+ }
83
+ ```
84
+
85
+ On deploy the plugin runs `vite build` at startup (and rebuilds when `files` change) while `static` serves the result. If you prefer to build in CI, commit the build output, point `static` at it, and omit `files` so the plugin stays idle while `static` serves the prebuilt assets. Either way, `npm create harper@latest` scaffolds a working setup for you.
package/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  .DS_Store
2
- web
3
- deploy
2
+ dist
4
3
 
5
4
  #
6
5
  # https://raw.githubusercontent.com/github/gitignore/refs/heads/main/Node.gitignore
package/README.md CHANGED
@@ -73,7 +73,7 @@ These schemas are the heart of a great Harper app, specifying which tables you w
73
73
 
74
74
  ### View Your Website
75
75
 
76
- Pop open [http://localhost:9926](http://localhost:9926) to view [web/index.html](./web/index.html) in your browser.
76
+ Pop open [http://localhost:9926](http://localhost:9926) to view [index.html](./index.html) in your browser.
77
77
 
78
78
  ### Use Your API
79
79
 
package/config.yaml CHANGED
@@ -20,6 +20,19 @@ jsResource:
20
20
  files: 'resources/*.ts'
21
21
 
22
22
  # Generates types for the schema so your code is schema-aware
23
- # Bootstraps Vite to build your frontend to HTML/JS/CSS
24
- '@harperfast/vite-plugin':
25
- package: '@harperfast/vite-plugin'
23
+ # Bootstraps Vite to build your frontend to HTML/JS/CSS.
24
+ # In production it builds your app (and recompiles when files in `files` change); the `static`
25
+ # component below serves the built output. Listed before `static` so its dev server wins in `harper dev`.
26
+ '@harperfast/vite':
27
+ package: '@harperfast/vite'
28
+ files: 'src/**/*'
29
+ output: 'dist'
30
+
31
+ # Serves the built frontend from Vite's output directory. `notFound` + `fallthrough: false` makes
32
+ # client-side routing work (unmatched routes return index.html); the REST routes above take precedence.
33
+ static:
34
+ files: 'dist/**'
35
+ notFound:
36
+ file: 'index.html'
37
+ statusCode: 200
38
+ fallthrough: false
package/package.json CHANGED
@@ -1,8 +1,15 @@
1
1
  {
2
2
  "name": "@harperfast/template-vue-ts-studio",
3
- "version": "1.7.4",
3
+ "version": "1.8.2",
4
4
  "type": "module",
5
5
  "repository": "github:HarperFast/create-harper",
6
6
  "scripts": {},
7
+ "dependencies": {
8
+ "@harperfast/schema-codegen": "^1.0.10",
9
+ "@harperfast/vite": "^1.1.0",
10
+ "@vitejs/plugin-vue": "^6.0.5",
11
+ "vite": "^8.0.0",
12
+ "vue": "^3.5.29"
13
+ },
7
14
  "devDependencies": {}
8
15
  }
package/skills-lock.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "source": "harperfast/skills",
6
6
  "sourceType": "github",
7
7
  "skillPath": "harper-best-practices/SKILL.md",
8
- "computedHash": "921b0848ec9f7ee375fec2d4191c99325e1d7160c0ab463832b3e0443e80576a"
8
+ "computedHash": "8aa6811090a5ef3721428b048f3c1208fc50d93b5fe03acad27d89a416a081a1"
9
9
  }
10
10
  }
11
11
  }
package/vite.config.ts CHANGED
@@ -13,7 +13,7 @@ export default defineConfig({
13
13
  },
14
14
  },
15
15
  build: {
16
- outDir: 'web',
16
+ outDir: 'dist',
17
17
  emptyOutDir: true,
18
18
  rolldownOptions: {
19
19
  external: ['**/*.test.*', '**/*.spec.*'],
@@ -1,10 +0,0 @@
1
- fastifyRoutes:
2
- files: fastify/*.js
3
-
4
- rest: true
5
-
6
- graphqlSchema:
7
- files: 'schemas/*.graphql'
8
-
9
- jsResource:
10
- files: 'resources/*.ts'
@@ -1,14 +0,0 @@
1
- import fastifyStatic from '@fastify/static';
2
- import { join } from 'path';
3
-
4
- export default async (fastify) => {
5
- fastify.register(fastifyStatic, {
6
- root: join(import.meta.dirname, '../web'),
7
- maxAge: '30d',
8
- immutable: true,
9
- });
10
-
11
- fastify.get('/', function(req, reply) {
12
- reply.sendFile('index.html', { maxAge: '1m', immutable: false });
13
- });
14
- };
@@ -1,5 +0,0 @@
1
- {
2
- "dependencies": {
3
- "@fastify/static": "^9.0.0"
4
- }
5
- }