create-react-adam 0.5.0 → 0.6.0
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 +21 -2
- package/bin/index.js +33 -0
- package/package.json +1 -1
- package/template/README.md +24 -1
- package/template/index.html +1 -0
- package/template/package.json +4 -3
- package/template/public/favicon.svg +9 -0
- package/template/vite.config.no-pwa.ts +7 -0
- package/template/vite.config.ts +50 -1
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Running without flags opens an interactive wizard where you pick features
|
|
|
19
19
|
│ ◼ Utility functions (classNames, Storage, useUrlState, safeTimeout)
|
|
20
20
|
│ ◼ Lighthouse CI workflow (a11y/SEO/performance budgets)
|
|
21
21
|
│ ◼ ESLint rule: prefer WebP images
|
|
22
|
+
│ ◼ PWA (installable app + offline support via vite-plugin-pwa)
|
|
22
23
|
└
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -42,8 +43,9 @@ Running without flags opens an interactive wizard where you pick features
|
|
|
42
43
|
- `--with-utils` / `--no-utils` - Include or skip utility functions
|
|
43
44
|
- `--with-lighthouse` / `--no-lighthouse` - Include or skip the Lighthouse CI workflow
|
|
44
45
|
- `--with-webp-lint` / `--no-webp-lint` - Include or skip the prefer-webp-images ESLint rule
|
|
46
|
+
- `--with-pwa` / `--no-pwa` - Include or skip PWA support (installable, works offline)
|
|
45
47
|
|
|
46
|
-
Any feature answered by a flag is removed from the wizard; if all
|
|
48
|
+
Any feature answered by a flag is removed from the wizard; if all five are
|
|
47
49
|
answered, the wizard is skipped entirely.
|
|
48
50
|
|
|
49
51
|
## What's Included
|
|
@@ -67,7 +69,7 @@ Every generated project starts with:
|
|
|
67
69
|
idle prefetcher warms the rest after first paint (documented in the
|
|
68
70
|
generated README, easy to remove)
|
|
69
71
|
- **SEO-ready `index.html`** - meta description, Open Graph and Twitter card
|
|
70
|
-
tags, theme-color, plus a `public/robots.txt`
|
|
72
|
+
tags, theme-color, an SVG favicon, plus a `public/robots.txt`
|
|
71
73
|
- **Accessible shell** - skip-to-content link, `<main>` landmark, visible
|
|
72
74
|
`:focus-visible` styles, and per-route document titles
|
|
73
75
|
|
|
@@ -102,6 +104,22 @@ When you include E2E testing (via wizard or `--with-e2e` flag), you get:
|
|
|
102
104
|
- Pre-configured test setup with example tests
|
|
103
105
|
- HTML reports and Allure integration
|
|
104
106
|
|
|
107
|
+
### Optional PWA Support
|
|
108
|
+
|
|
109
|
+
When you include PWA support (via wizard or `--with-pwa` flag), the app
|
|
110
|
+
becomes an installable Progressive Web App:
|
|
111
|
+
|
|
112
|
+
- **vite-plugin-pwa** configured in `vite.config.ts`, with comments explaining
|
|
113
|
+
every option
|
|
114
|
+
- Production builds generate a precaching service worker (`dist/sw.js`) and a
|
|
115
|
+
web app manifest (`dist/manifest.webmanifest`); the registration script is
|
|
116
|
+
injected into `index.html` automatically
|
|
117
|
+
- The app shell (JS, CSS, HTML, SVG, fonts) works offline after the first
|
|
118
|
+
visit, and client-side routes fall back to the cached `index.html`
|
|
119
|
+
- `registerType: "autoUpdate"` means new deployments replace the old service
|
|
120
|
+
worker automatically — no "refresh to update" prompt
|
|
121
|
+
- Dev mode is unchanged: the service worker only exists in production builds
|
|
122
|
+
|
|
105
123
|
### Git Integration
|
|
106
124
|
|
|
107
125
|
After scaffolding (when not already inside a git repository), the CLI:
|
|
@@ -202,6 +220,7 @@ Runs basic troubleshooting checks:
|
|
|
202
220
|
```
|
|
203
221
|
my-app/
|
|
204
222
|
├── public/
|
|
223
|
+
│ ├── favicon.svg # App icon (also used by the PWA manifest)
|
|
205
224
|
│ ├── fonts/ # Self-hosted Inter (variable woff2)
|
|
206
225
|
│ └── robots.txt
|
|
207
226
|
├── src/
|
package/bin/index.js
CHANGED
|
@@ -32,6 +32,11 @@ const FEATURES = [
|
|
|
32
32
|
id: 'webpLint',
|
|
33
33
|
flag: 'webp-lint',
|
|
34
34
|
label: 'ESLint rule: prefer WebP images'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'pwa',
|
|
38
|
+
flag: 'pwa',
|
|
39
|
+
label: 'PWA (installable app + offline support via vite-plugin-pwa)'
|
|
35
40
|
}
|
|
36
41
|
];
|
|
37
42
|
|
|
@@ -97,6 +102,8 @@ function printUsage() {
|
|
|
97
102
|
console.log(' --no-lighthouse Skip Lighthouse CI workflow');
|
|
98
103
|
console.log(' --with-webp-lint Include the prefer-webp-images ESLint rule');
|
|
99
104
|
console.log(' --no-webp-lint Skip the prefer-webp-images ESLint rule');
|
|
105
|
+
console.log(' --with-pwa Include PWA support (installable, works offline)');
|
|
106
|
+
console.log(' --no-pwa Skip PWA support');
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
async function resolveFeatures(flags) {
|
|
@@ -339,6 +346,22 @@ async function main() {
|
|
|
339
346
|
}
|
|
340
347
|
await rm(noWebpConfigPath);
|
|
341
348
|
|
|
349
|
+
// Resolve the vite config variant: the template's vite.config.ts is the
|
|
350
|
+
// PWA version (vite-plugin-pwa + web app manifest); vite.config.no-pwa.ts
|
|
351
|
+
// is the plain version used when the PWA feature is skipped. When PWA is
|
|
352
|
+
// off, also drop the now-unused vite-plugin-pwa devDependency so it never
|
|
353
|
+
// gets installed.
|
|
354
|
+
const noPwaConfigPath = join(projectPath, 'vite.config.no-pwa.ts');
|
|
355
|
+
if (!features.pwa) {
|
|
356
|
+
await copyFile(noPwaConfigPath, join(projectPath, 'vite.config.ts'));
|
|
357
|
+
|
|
358
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
359
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
360
|
+
delete pkg.devDependencies['vite-plugin-pwa'];
|
|
361
|
+
await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, 'utf-8');
|
|
362
|
+
}
|
|
363
|
+
await rm(noPwaConfigPath);
|
|
364
|
+
|
|
342
365
|
// README.md uses {{PROJECT_NAME}} because Prettier's markdown formatter
|
|
343
366
|
// rewrites __PROJECT_NAME__ (underscore emphasis) to **PROJECT_NAME**.
|
|
344
367
|
const replacements = {
|
|
@@ -350,6 +373,9 @@ async function main() {
|
|
|
350
373
|
'package.json',
|
|
351
374
|
'index.html',
|
|
352
375
|
'README.md',
|
|
376
|
+
// vite.config.ts only has placeholders in its PWA variant (the web app
|
|
377
|
+
// manifest name); replacing is a harmless no-op otherwise.
|
|
378
|
+
'vite.config.ts',
|
|
353
379
|
join('src', 'pages', 'Home', 'index.tsx'),
|
|
354
380
|
join('src', 'pages', 'About', 'index.tsx'),
|
|
355
381
|
join('src', 'pages', 'NotFound', 'index.tsx')
|
|
@@ -395,6 +421,13 @@ async function main() {
|
|
|
395
421
|
console.log(' Generates and opens Allure report.\n');
|
|
396
422
|
}
|
|
397
423
|
|
|
424
|
+
if (features.pwa) {
|
|
425
|
+
console.log(
|
|
426
|
+
'PWA support is on: production builds generate a service worker and web' +
|
|
427
|
+
'\napp manifest (configured in vite.config.ts); dev mode is unaffected.\n'
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
398
431
|
console.log('We suggest that you begin by typing:\n');
|
|
399
432
|
console.log(` cd ${projectName}`);
|
|
400
433
|
console.log(' npm run dev\n');
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -122,10 +122,33 @@ location makes it smooth.
|
|
|
122
122
|
- **Fonts**: Inter is self-hosted from `public/fonts/` (variable `woff2`,
|
|
123
123
|
`font-display: swap`, preloaded in `index.html`). No third-party requests.
|
|
124
124
|
- **SEO**: `index.html` ships meta description, Open Graph, and Twitter card
|
|
125
|
-
tags — update them as your app takes shape. `public/robots.txt`
|
|
125
|
+
tags — update them as your app takes shape. `public/robots.txt` and an SVG
|
|
126
|
+
favicon (`public/favicon.svg`) are included.
|
|
126
127
|
- **Accessibility**: a skip-to-content link, `<main>` landmark, and visible
|
|
127
128
|
`:focus-visible` styles are wired into `App.tsx` / `app.css`.
|
|
128
129
|
|
|
130
|
+
## PWA (if included)
|
|
131
|
+
|
|
132
|
+
This app is a Progressive Web App: browsers offer an "Install" option, and
|
|
133
|
+
the app keeps working offline after the first visit.
|
|
134
|
+
|
|
135
|
+
- Everything is configured in `vite.config.ts` via
|
|
136
|
+
[vite-plugin-pwa](https://vite-pwa-org.netlify.app) — the web app manifest
|
|
137
|
+
(name, colors, icon) lives there too. Update it alongside the matching
|
|
138
|
+
values in `index.html` (`theme-color`) and `public/favicon.svg`.
|
|
139
|
+
- `npm run build` generates the service worker (`dist/sw.js`) and manifest
|
|
140
|
+
(`dist/manifest.webmanifest`) and injects the registration script into
|
|
141
|
+
`index.html` — no client code to maintain.
|
|
142
|
+
- The service worker precaches the app shell (JS, CSS, HTML, SVG, fonts) and
|
|
143
|
+
answers client-side routes with the cached `index.html` when offline.
|
|
144
|
+
- Updates are automatic (`registerType: "autoUpdate"`): a new deployment
|
|
145
|
+
replaces the old service worker on the user's next visit.
|
|
146
|
+
- Dev mode is unaffected — the service worker only exists in production
|
|
147
|
+
builds. Test it locally with `npm run build && npm run preview`.
|
|
148
|
+
|
|
149
|
+
To remove PWA support later: delete the `VitePWA(...)` block and its import
|
|
150
|
+
from `vite.config.ts`, then run `npm uninstall vite-plugin-pwa`.
|
|
151
|
+
|
|
129
152
|
## ESLint: prefer-webp-images (if included)
|
|
130
153
|
|
|
131
154
|
A local rule in `eslint-rules/prefer-webp-images.js` errors on references to
|
package/template/index.html
CHANGED
package/template/package.json
CHANGED
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"@types/react": "19.2.17",
|
|
31
31
|
"@types/react-dom": "19.2.3",
|
|
32
32
|
"@vitejs/plugin-react": "6.0.3",
|
|
33
|
-
"eslint": "10.
|
|
33
|
+
"eslint": "10.7.0",
|
|
34
34
|
"eslint-config-prettier": "10.1.8",
|
|
35
35
|
"eslint-import-resolver-typescript": "4.4.5",
|
|
36
|
-
"eslint-plugin-de-morgan": "2.1.
|
|
36
|
+
"eslint-plugin-de-morgan": "2.1.3",
|
|
37
37
|
"eslint-plugin-import-x": "4.17.1",
|
|
38
38
|
"eslint-plugin-jsx-a11y": "6.10.2",
|
|
39
39
|
"eslint-plugin-promise": "7.3.0",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"tailwindcss": "4.3.2",
|
|
47
47
|
"typescript": "6.0.3",
|
|
48
48
|
"typescript-eslint": "8.63.0",
|
|
49
|
-
"vite": "8.1.4"
|
|
49
|
+
"vite": "8.1.4",
|
|
50
|
+
"vite-plugin-pwa": "1.3.0"
|
|
50
51
|
},
|
|
51
52
|
"overrides": {
|
|
52
53
|
"eslint-plugin-jsx-a11y": {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
2
|
+
<rect width="512" height="512" rx="96" fill="#2563eb" />
|
|
3
|
+
<g fill="none" stroke="#ffffff" stroke-width="20">
|
|
4
|
+
<ellipse cx="256" cy="256" rx="176" ry="72" />
|
|
5
|
+
<ellipse cx="256" cy="256" rx="176" ry="72" transform="rotate(60 256 256)" />
|
|
6
|
+
<ellipse cx="256" cy="256" rx="176" ry="72" transform="rotate(120 256 256)" />
|
|
7
|
+
</g>
|
|
8
|
+
<circle cx="256" cy="256" r="28" fill="#ffffff" />
|
|
9
|
+
</svg>
|
package/template/vite.config.ts
CHANGED
|
@@ -1,7 +1,56 @@
|
|
|
1
1
|
import tailwindcss from "@tailwindcss/vite";
|
|
2
2
|
import react from "@vitejs/plugin-react";
|
|
3
3
|
import { defineConfig } from "vite";
|
|
4
|
+
import { VitePWA } from "vite-plugin-pwa";
|
|
4
5
|
|
|
6
|
+
// PWA support (optional create-react-adam feature). vite-plugin-pwa makes
|
|
7
|
+
// the app installable and offline-capable: `npm run build` generates a
|
|
8
|
+
// service worker (dist/sw.js) that precaches the app shell, emits a web app
|
|
9
|
+
// manifest (dist/manifest.webmanifest), and injects the registration script
|
|
10
|
+
// into index.html. `npm run dev` is unaffected — the service worker only
|
|
11
|
+
// exists in production builds; test it locally with
|
|
12
|
+
// `npm run build && npm run preview`. Docs: https://vite-pwa-org.netlify.app
|
|
5
13
|
export default defineConfig({
|
|
6
|
-
plugins: [
|
|
14
|
+
plugins: [
|
|
15
|
+
react(),
|
|
16
|
+
tailwindcss(),
|
|
17
|
+
VitePWA({
|
|
18
|
+
// New deployments take over automatically on the user's next visit —
|
|
19
|
+
// no "refresh to update" prompt, no stale app shell.
|
|
20
|
+
registerType: "autoUpdate",
|
|
21
|
+
workbox: {
|
|
22
|
+
// Precache all built JS/CSS/HTML plus SVGs and the self-hosted
|
|
23
|
+
// fonts, so the entire app shell works offline after the first
|
|
24
|
+
// visit. Add extensions here if you ship other static assets
|
|
25
|
+
// (e.g. png, webp) that should be available offline.
|
|
26
|
+
globPatterns: ["**/*.{js,css,html,svg,woff2}"],
|
|
27
|
+
// SPA fallback: deep links like /about are client-side routes, so
|
|
28
|
+
// the service worker answers them with the cached index.html when
|
|
29
|
+
// offline instead of failing with a network error.
|
|
30
|
+
navigateFallback: "index.html",
|
|
31
|
+
},
|
|
32
|
+
// The install metadata browsers read for "Install app" / "Add to
|
|
33
|
+
// Home Screen": the installed app's name, icon, and window colors.
|
|
34
|
+
manifest: {
|
|
35
|
+
name: "__PROJECT_NAME__",
|
|
36
|
+
short_name: "__PROJECT_NAME__",
|
|
37
|
+
description: "A React app built with create-react-adam",
|
|
38
|
+
// Keep in sync with the theme-color <meta> tag in index.html.
|
|
39
|
+
theme_color: "#2563eb",
|
|
40
|
+
// Splash-screen background while the app loads; matches
|
|
41
|
+
// --color-brand-background in src/app.css.
|
|
42
|
+
background_color: "#f8fafc",
|
|
43
|
+
display: "standalone",
|
|
44
|
+
icons: [
|
|
45
|
+
{
|
|
46
|
+
// SVG icons scale to any size; swap in 192x192 and 512x512
|
|
47
|
+
// PNGs here if you need to support older devices.
|
|
48
|
+
src: "/favicon.svg",
|
|
49
|
+
sizes: "any",
|
|
50
|
+
type: "image/svg+xml",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
7
56
|
});
|