create-spark-html-app 0.7.1 → 0.8.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 +14 -12
- package/bin/index.js +8 -7
- package/package.json +3 -3
- package/template/README.md +7 -7
- package/template/_gitignore +0 -1
- package/template/package.json +5 -5
- package/template/public/components/demo-image.html +1 -1
- package/template/spark.config.js +52 -0
- package/template/src/main.js +1 -1
- package/template/vite.config.js +0 -55
package/README.md
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
# create-spark-html-app
|
|
2
2
|
|
|
3
|
-
Scaffold a [Spark](https://github.com/wilkinnovo/spark) app in seconds — a
|
|
4
|
-
project
|
|
3
|
+
Scaffold a [Spark](https://github.com/wilkinnovo/spark) app in seconds — a
|
|
4
|
+
Bun-powered project (dev / build / preview via `spark-html-bun`) wired to
|
|
5
|
+
`spark-html` with live, reactive **Spark** components.
|
|
5
6
|
|
|
6
7
|
## Usage
|
|
7
8
|
|
|
8
9
|
```bash
|
|
9
|
-
|
|
10
|
+
bun create spark-html-app my-app
|
|
10
11
|
# or
|
|
11
|
-
|
|
12
|
+
bunx create-spark-html-app my-app
|
|
12
13
|
```
|
|
13
14
|
|
|
14
15
|
Then:
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
18
|
cd my-app
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
bun install
|
|
20
|
+
bun run dev
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
Run it with no name to be prompted:
|
|
23
24
|
|
|
24
25
|
```bash
|
|
25
|
-
|
|
26
|
+
bun create spark-html-app
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
## What you get
|
|
@@ -43,10 +44,10 @@ Every included feature ships with a live demo component, ready to run.
|
|
|
43
44
|
Non-interactive? Pass flags instead of answering prompts:
|
|
44
45
|
|
|
45
46
|
```bash
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
bunx create-spark-html-app my-app --yes # accept the defaults
|
|
48
|
+
bunx create-spark-html-app my-app --all # everything on
|
|
49
|
+
bunx create-spark-html-app my-app --minimal # core only
|
|
50
|
+
bunx create-spark-html-app my-app --pwa --no-image # per-feature
|
|
50
51
|
```
|
|
51
52
|
|
|
52
53
|
Everything is plain HTML and JavaScript — no compiler, no virtual DOM, no
|
|
@@ -60,6 +61,7 @@ virtual DOM, no build step required. Add only what you use.
|
|
|
60
61
|
| Package | What it does |
|
|
61
62
|
|---|---|
|
|
62
63
|
| [`spark-html`](https://www.npmjs.com/package/spark-html) | The runtime — components, reactivity, stores, forms, scoped styles. 13 kB gzip, 0 deps. |
|
|
64
|
+
| [`spark-html-bun`](https://www.npmjs.com/package/spark-html-bun) | Dev server, bundler & preview on Bun — scoped HMR, no-build dev, post-build pipeline. |
|
|
63
65
|
| [`spark-html-router`](https://www.npmjs.com/package/spark-html-router) | `<template route>` routing — nested routes/layouts, `route.query`, active links. |
|
|
64
66
|
| [`spark-html-theme`](https://www.npmjs.com/package/spark-html-theme) | Dark/light/system theming in one line — persisted, no flash. |
|
|
65
67
|
| [`spark-html-head`](https://www.npmjs.com/package/spark-html-head) | Reactive `<title>`/`<meta>` per route + a `head` store. |
|
|
@@ -74,7 +76,7 @@ virtual DOM, no build step required. Add only what you use.
|
|
|
74
76
|
| [`spark-html-manifest`](https://www.npmjs.com/package/spark-html-manifest) | PWA manifest + icons + head tags (and optional service worker) from one config. |
|
|
75
77
|
| [`spark-html-offline`](https://www.npmjs.com/package/spark-html-offline) | Offline URL imports — a service worker that caches CDN components. |
|
|
76
78
|
| [`spark-html-sri`](https://www.npmjs.com/package/spark-html-sri) | Subresource Integrity — hash + verify assets and remote components. |
|
|
77
|
-
| [`create-spark-html-app`](https://www.npmjs.com/package/create-spark-html-app) | Scaffold a
|
|
79
|
+
| [`create-spark-html-app`](https://www.npmjs.com/package/create-spark-html-app) | Scaffold a spark-html app in one command. |
|
|
78
80
|
| [`prettier-plugin-spark`](https://www.npmjs.com/package/prettier-plugin-spark) | Prettier for components — formats `<script>`/`<style>`, markup stays byte-for-byte. |
|
|
79
81
|
| [`spark-html-language-server`](https://www.npmjs.com/package/spark-html-language-server) | LSP — diagnostics, go-to-definition, prop autocomplete, hover docs. |
|
|
80
82
|
|
package/bin/index.js
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* npm create spark-html-app@latest my-app
|
|
6
6
|
* npx create-spark-html-app my-app
|
|
7
7
|
*
|
|
8
|
-
* Scaffolds a ready-to-run
|
|
9
|
-
* reactive "Welcome to Spark" screen.
|
|
10
|
-
* just Node built-ins, in keeping with
|
|
8
|
+
* Scaffolds a ready-to-run spark-html project (dev/build/preview on Bun,
|
|
9
|
+
* via spark-html-bun) with a live, reactive "Welcome to Spark" screen.
|
|
10
|
+
* Zero runtime dependencies — just Node built-ins, in keeping with
|
|
11
|
+
* Spark's no-build ethos.
|
|
11
12
|
*/
|
|
12
13
|
import { fileURLToPath } from 'node:url';
|
|
13
14
|
import { dirname, join, resolve, relative, basename } from 'node:path';
|
|
@@ -236,8 +237,8 @@ async function main() {
|
|
|
236
237
|
}
|
|
237
238
|
// PWA config carries the app's display name.
|
|
238
239
|
if (features.pwa) {
|
|
239
|
-
const
|
|
240
|
-
writeFileSync(
|
|
240
|
+
const cfgPath = join(targetDir, 'spark.config.js');
|
|
241
|
+
writeFileSync(cfgPath, readFileSync(cfgPath, 'utf8').replace("name: 'Spark App'", `name: '${projectName}'`), 'utf8');
|
|
241
242
|
}
|
|
242
243
|
// Always start on the newest published versions of the spark packages. If the
|
|
243
244
|
// registry can't be reached (or a package isn't published yet), the template's
|
|
@@ -262,8 +263,8 @@ async function main() {
|
|
|
262
263
|
stdout.write(`\n${c.green('✔')} Scaffolded ${c.bold(projectName)} in ${c.cyan(rel)} ${c.dim(`(head, persist, prerender, devtools + ${picked})`)}\n\n`);
|
|
263
264
|
stdout.write(`${c.bold('Next steps:')}\n`);
|
|
264
265
|
if (rel !== '.') stdout.write(` ${c.dim('1.')} cd ${rel}\n`);
|
|
265
|
-
stdout.write(` ${c.dim(rel !== '.' ? '2.' : '1.')}
|
|
266
|
-
stdout.write(` ${c.dim(rel !== '.' ? '3.' : '2.')}
|
|
266
|
+
stdout.write(` ${c.dim(rel !== '.' ? '2.' : '1.')} bun install\n`);
|
|
267
|
+
stdout.write(` ${c.dim(rel !== '.' ? '3.' : '2.')} bun dev\n\n`);
|
|
267
268
|
stdout.write(`${BOLT} Then open the dev server and edit ${c.cyan('public/components/hero.html')}.\n\n`);
|
|
268
269
|
}
|
|
269
270
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-spark-html-app",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Scaffold a
|
|
3
|
+
"version": "0.8.1",
|
|
4
|
+
"description": "Scaffold a spark-html app — dev/build/preview on Bun",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-spark-html-app": "bin/index.js"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"create",
|
|
25
25
|
"scaffold",
|
|
26
26
|
"cli",
|
|
27
|
-
"
|
|
27
|
+
"bun",
|
|
28
28
|
"reactive",
|
|
29
29
|
"html",
|
|
30
30
|
"no-build"
|
package/template/README.md
CHANGED
|
@@ -14,8 +14,8 @@ icons + offline app shell). `spark-html-head`, `spark-html-persist`,
|
|
|
14
14
|
## Develop
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
bun install
|
|
18
|
+
bun run dev # dev server with HMR
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
In dev mode, `spark-html-devtools` adds a debugging overlay — inspect
|
|
@@ -24,12 +24,12 @@ component state, stores, and the mounted tree live.
|
|
|
24
24
|
## Build (SEO-ready)
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
bun run build # static output → dist/, serve anywhere
|
|
28
|
+
bun run preview # preview the production build locally
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
`
|
|
32
|
-
|
|
31
|
+
`bun run build` is **SEO-friendly out of the box**: the `spark-prerender`
|
|
32
|
+
pipeline step runs your app at build time and writes fully-rendered HTML into
|
|
33
33
|
`dist/` — so crawlers and AI tools read real content (headings, text, links),
|
|
34
34
|
not empty placeholders. The browser still hydrates over it for full
|
|
35
35
|
interactivity.
|
|
@@ -37,7 +37,7 @@ interactivity.
|
|
|
37
37
|
Per-route `<title>` and `<meta>` tags are set reactively via
|
|
38
38
|
`spark-html-head` in `src/main.js` — no per-component boilerplate.
|
|
39
39
|
|
|
40
|
-
Don't need SEO? Remove the `prerender(...)`
|
|
40
|
+
Don't need SEO? Remove the `prerender(...)` step from `spark.config.js`.
|
|
41
41
|
|
|
42
42
|
## Architecture
|
|
43
43
|
|
package/template/_gitignore
CHANGED
package/template/package.json
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
"version": "0.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "
|
|
8
|
-
"build": "
|
|
9
|
-
"preview": "
|
|
7
|
+
"dev": "spark dev",
|
|
8
|
+
"build": "spark build",
|
|
9
|
+
"preview": "spark preview"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"spark-html": "latest",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"spark-html-manifest": "latest"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
+
"spark-html-bun": "latest",
|
|
21
22
|
"spark-prerender": "latest",
|
|
22
23
|
"spark-html-devtools": "latest",
|
|
23
|
-
"spark-html-image": "latest"
|
|
24
|
-
"vite": "^8.1.0"
|
|
24
|
+
"spark-html-image": "latest"
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<p class="hint">
|
|
6
6
|
A plain <code><img></code> — at build time it becomes a
|
|
7
7
|
<code><picture></code> with webp/avif srcset, width/height, and lazy
|
|
8
|
-
loading. Run <code>
|
|
8
|
+
loading. Run <code>bun run build</code> and inspect <code>dist/</code>.
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<img class="shot" src="/sample.jpg" alt="Sample image — optimized at build time" />
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import prerender from 'spark-prerender/bun';
|
|
2
|
+
// @spark:image
|
|
3
|
+
import image from 'spark-html-image/bun';
|
|
4
|
+
// @spark:end
|
|
5
|
+
// @spark:pwa
|
|
6
|
+
import manifest from 'spark-html-manifest/bun';
|
|
7
|
+
// @spark:end
|
|
8
|
+
// @spark:sri
|
|
9
|
+
import sri from 'spark-html-sri/bun';
|
|
10
|
+
// @spark:end
|
|
11
|
+
|
|
12
|
+
// Spark needs no build step — spark-html-bun is just a fast dev server and a
|
|
13
|
+
// bundler for your app shell. `spark dev` serves component fragments raw and
|
|
14
|
+
// hot-reloads only the edited component; components live in public/ so they
|
|
15
|
+
// ship verbatim to the production build too.
|
|
16
|
+
//
|
|
17
|
+
// The `pipeline` runs in order after `spark build` copies public/ and bundles
|
|
18
|
+
// the entry. Order matters: prerender() first (it writes one HTML file per
|
|
19
|
+
// route), then the steps that rewrite those pages — sri() must be last so it
|
|
20
|
+
// hashes the final bytes.
|
|
21
|
+
//
|
|
22
|
+
// `prerender()` makes `bun run build` SEO-friendly: it runs your app at build
|
|
23
|
+
// time and writes fully-rendered HTML into dist/ (crawlers and AI tools read
|
|
24
|
+
// real content; the browser still hydrates over it), plus sitemap.xml +
|
|
25
|
+
// robots.txt. Remove it if you don't need SEO.
|
|
26
|
+
export default {
|
|
27
|
+
pipeline: [
|
|
28
|
+
prerender({ pages: ['index.html'] }),
|
|
29
|
+
// @spark:image
|
|
30
|
+
// Every <img> in pages and components: converted to webp/avif at multiple
|
|
31
|
+
// widths, srcset + width/height added (no layout shift), loading="lazy".
|
|
32
|
+
// Zero config.
|
|
33
|
+
image(),
|
|
34
|
+
// @spark:end
|
|
35
|
+
// @spark:pwa
|
|
36
|
+
// One config → manifest.webmanifest + resized icons + <head> tags + an
|
|
37
|
+
// offline app-shell service worker (registered automatically).
|
|
38
|
+
manifest({
|
|
39
|
+
name: 'Spark App',
|
|
40
|
+
themeColor: '#ffd24a',
|
|
41
|
+
icon: 'public/icon.png',
|
|
42
|
+
offline: true,
|
|
43
|
+
}),
|
|
44
|
+
// @spark:end
|
|
45
|
+
// @spark:sri
|
|
46
|
+
// Hashes every built asset + component, stamps integrity/crossorigin onto
|
|
47
|
+
// script/link tags, and bakes the verify manifest into each page. Keep it
|
|
48
|
+
// LAST so it sees the final pages.
|
|
49
|
+
sri(),
|
|
50
|
+
// @spark:end
|
|
51
|
+
],
|
|
52
|
+
};
|
package/template/src/main.js
CHANGED
|
@@ -45,7 +45,7 @@ theme();
|
|
|
45
45
|
|
|
46
46
|
// @spark:pwa
|
|
47
47
|
// PWA: manifest.webmanifest, icons, and the offline app-shell worker are
|
|
48
|
-
// generated by spark-html-manifest/
|
|
48
|
+
// generated by spark-html-manifest/bun (see spark.config.js) — the worker
|
|
49
49
|
// registration is injected into every built page automatically.
|
|
50
50
|
// Want offline-capable CDN component imports too? See spark-html-offline
|
|
51
51
|
// (a page registers one worker per scope, so pick the one you need).
|
package/template/vite.config.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import spark from 'spark-html/vite';
|
|
3
|
-
import prerender from 'spark-prerender/vite';
|
|
4
|
-
// @spark:image
|
|
5
|
-
import image from 'spark-html-image/vite';
|
|
6
|
-
// @spark:end
|
|
7
|
-
// @spark:pwa
|
|
8
|
-
import manifest from 'spark-html-manifest/vite';
|
|
9
|
-
// @spark:end
|
|
10
|
-
// @spark:sri
|
|
11
|
-
import sri from 'spark-html-sri/vite';
|
|
12
|
-
// @spark:end
|
|
13
|
-
|
|
14
|
-
// Spark needs no build step — Vite is just a convenient dev server and
|
|
15
|
-
// bundler. The plugin serves component fragments raw and full-reloads
|
|
16
|
-
// when one changes. Components live in public/ so they ship verbatim to
|
|
17
|
-
// the production build too.
|
|
18
|
-
//
|
|
19
|
-
// `prerender()` makes `npm run build` SEO-friendly: it runs your app at
|
|
20
|
-
// build time and writes fully-rendered HTML into dist/ (crawlers and AI
|
|
21
|
-
// tools read real content; the browser still hydrates over it), plus
|
|
22
|
-
// sitemap.xml + robots.txt. Remove it if you don't need SEO.
|
|
23
|
-
export default defineConfig({
|
|
24
|
-
optimizeDeps: {
|
|
25
|
-
// Ensure spark-html is pre-bundled so all modules share the same stores Map.
|
|
26
|
-
// Without this, file: references can create duplicate runtime instances.
|
|
27
|
-
include: ['spark-html'],
|
|
28
|
-
},
|
|
29
|
-
plugins: [
|
|
30
|
-
spark(),
|
|
31
|
-
// @spark:image
|
|
32
|
-
// Every <img> in pages and components: converted to webp/avif at
|
|
33
|
-
// multiple widths, wrapped in <picture> with srcset, width/height
|
|
34
|
-
// added (no layout shift), loading="lazy". Zero config.
|
|
35
|
-
image(),
|
|
36
|
-
// @spark:end
|
|
37
|
-
prerender({ pages: ['index.html'] }),
|
|
38
|
-
// @spark:pwa
|
|
39
|
-
// One config → manifest.webmanifest + resized icons + <head> tags +
|
|
40
|
-
// an offline app-shell service worker (registered automatically).
|
|
41
|
-
manifest({
|
|
42
|
-
name: 'Spark App',
|
|
43
|
-
themeColor: '#ffd24a',
|
|
44
|
-
icon: 'public/icon.png',
|
|
45
|
-
offline: true,
|
|
46
|
-
}),
|
|
47
|
-
// @spark:end
|
|
48
|
-
// @spark:sri
|
|
49
|
-
// Hashes every built asset + component, stamps integrity/crossorigin
|
|
50
|
-
// onto script/link tags, and bakes the verify manifest into each page.
|
|
51
|
-
// Keep it AFTER prerender() so it sees the final pages.
|
|
52
|
-
sri(),
|
|
53
|
-
// @spark:end
|
|
54
|
-
],
|
|
55
|
-
});
|