create-what 0.1.1 → 0.1.3
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/index.js +257 -24
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// create-what: npm create what@latest my-app
|
|
4
|
-
// Scaffolds a new What
|
|
4
|
+
// Scaffolds a new What Framework project with sensible defaults.
|
|
5
|
+
//
|
|
6
|
+
// Usage:
|
|
7
|
+
// npm create what@latest my-app # JSX project (default)
|
|
8
|
+
// npm create what@latest my-app --no-jsx # vanilla h() project
|
|
9
|
+
// npm create what@latest my-app --vanilla # vanilla h() project
|
|
5
10
|
|
|
6
11
|
import { mkdirSync, writeFileSync, existsSync } from 'fs';
|
|
7
12
|
import { join } from 'path';
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
const
|
|
14
|
+
// --- Parse CLI arguments ---
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
const flags = args.filter(a => a.startsWith('-'));
|
|
17
|
+
const positional = args.filter(a => !a.startsWith('-'));
|
|
18
|
+
|
|
19
|
+
const name = positional[0] || 'my-what-app';
|
|
20
|
+
const template = positional[1] || 'default'; // default | minimal | full
|
|
21
|
+
|
|
22
|
+
// JSX is the default; opt out with --no-jsx or --vanilla
|
|
23
|
+
const useJSX = !flags.includes('--no-jsx') && !flags.includes('--vanilla');
|
|
24
|
+
|
|
11
25
|
const cwd = process.cwd();
|
|
12
26
|
const root = join(cwd, name);
|
|
13
27
|
|
|
@@ -16,7 +30,11 @@ if (existsSync(root)) {
|
|
|
16
30
|
process.exit(1);
|
|
17
31
|
}
|
|
18
32
|
|
|
19
|
-
|
|
33
|
+
const mode = useJSX ? 'JSX' : 'vanilla (h())';
|
|
34
|
+
console.log(`\n Creating ${name} with template: ${template} (${mode})\n`);
|
|
35
|
+
|
|
36
|
+
// File extension helper
|
|
37
|
+
const ext = useJSX ? '.jsx' : '.js';
|
|
20
38
|
|
|
21
39
|
// Create directory structure
|
|
22
40
|
const dirs = [
|
|
@@ -29,22 +47,49 @@ const dirs = [
|
|
|
29
47
|
dirs.forEach(d => mkdirSync(join(root, d), { recursive: true }));
|
|
30
48
|
|
|
31
49
|
// --- package.json ---
|
|
32
|
-
|
|
50
|
+
const pkgDeps = {
|
|
51
|
+
'what-framework': '^0.1.0',
|
|
52
|
+
'what-framework-cli': '^0.1.0',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const pkgDevDeps = useJSX
|
|
56
|
+
? {
|
|
57
|
+
'what-compiler': '^0.1.0',
|
|
58
|
+
'@babel/core': '^7.23.0',
|
|
59
|
+
'vite': '^5.0.0',
|
|
60
|
+
}
|
|
61
|
+
: {};
|
|
62
|
+
|
|
63
|
+
const pkg = {
|
|
33
64
|
name,
|
|
34
65
|
private: true,
|
|
35
66
|
version: '0.0.1',
|
|
36
67
|
type: 'module',
|
|
37
68
|
scripts: {
|
|
38
|
-
dev: 'what dev',
|
|
39
|
-
build: 'what build',
|
|
40
|
-
preview: 'what preview',
|
|
69
|
+
dev: useJSX ? 'vite' : 'what dev',
|
|
70
|
+
build: useJSX ? 'vite build' : 'what build',
|
|
71
|
+
preview: useJSX ? 'vite preview' : 'what preview',
|
|
41
72
|
generate: 'what generate',
|
|
42
73
|
},
|
|
43
|
-
dependencies:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
74
|
+
dependencies: pkgDeps,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
if (Object.keys(pkgDevDeps).length > 0) {
|
|
78
|
+
pkg.devDependencies = pkgDevDeps;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
writeFileSync(join(root, 'package.json'), JSON.stringify(pkg, null, 2) + '\n');
|
|
82
|
+
|
|
83
|
+
// --- vite.config.js (JSX only) ---
|
|
84
|
+
if (useJSX) {
|
|
85
|
+
writeFileSync(join(root, 'vite.config.js'), `import { defineConfig } from 'vite';
|
|
86
|
+
import what from 'what-compiler/vite';
|
|
87
|
+
|
|
88
|
+
export default defineConfig({
|
|
89
|
+
plugins: [what()],
|
|
90
|
+
});
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
48
93
|
|
|
49
94
|
// --- what.config.js ---
|
|
50
95
|
writeFileSync(join(root, 'what.config.js'), `// What Framework Configuration
|
|
@@ -63,8 +108,9 @@ export default {
|
|
|
63
108
|
};
|
|
64
109
|
`);
|
|
65
110
|
|
|
66
|
-
// ---
|
|
67
|
-
|
|
111
|
+
// --- index.html (root — required by Vite) ---
|
|
112
|
+
const appScript = useJSX ? '/src/app.jsx' : '/src/app.js';
|
|
113
|
+
writeFileSync(join(root, 'index.html'), `<!DOCTYPE html>
|
|
68
114
|
<html lang="en">
|
|
69
115
|
<head>
|
|
70
116
|
<meta charset="UTF-8">
|
|
@@ -74,14 +120,128 @@ writeFileSync(join(root, 'src/index.html'), `<!DOCTYPE html>
|
|
|
74
120
|
</head>
|
|
75
121
|
<body>
|
|
76
122
|
<div id="app"></div>
|
|
77
|
-
<script type="module" src="
|
|
123
|
+
<script type="module" src="${appScript}"></script>
|
|
78
124
|
</body>
|
|
79
125
|
</html>
|
|
80
126
|
`);
|
|
81
127
|
|
|
128
|
+
// ==========================================================================
|
|
129
|
+
// JSX templates
|
|
130
|
+
// ==========================================================================
|
|
131
|
+
if (useJSX) {
|
|
132
|
+
|
|
133
|
+
// --- src/app.jsx ---
|
|
134
|
+
writeFileSync(join(root, 'src/app.jsx'), `import { mount, signal } from 'what-framework';
|
|
135
|
+
import { Router, Link, defineRoutes } from 'what-framework/router';
|
|
136
|
+
import { Layout } from './layouts/main.jsx';
|
|
137
|
+
import { Home } from './pages/index.jsx';
|
|
138
|
+
import { About } from './pages/about.jsx';
|
|
139
|
+
|
|
140
|
+
const routes = defineRoutes({
|
|
141
|
+
'/': { component: Home, layout: Layout },
|
|
142
|
+
'/about': { component: About, layout: Layout },
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
function App() {
|
|
146
|
+
return <Router routes={routes} fallback={NotFound} />;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function NotFound() {
|
|
150
|
+
return (
|
|
151
|
+
<div class="not-found">
|
|
152
|
+
<h1>404</h1>
|
|
153
|
+
<p>Page not found</p>
|
|
154
|
+
<Link href="/">Go home</Link>
|
|
155
|
+
</div>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
mount(<App />, '#app');
|
|
160
|
+
`);
|
|
161
|
+
|
|
162
|
+
// --- src/layouts/main.jsx ---
|
|
163
|
+
writeFileSync(join(root, 'src/layouts/main.jsx'), `import { Nav } from '../components/nav.jsx';
|
|
164
|
+
|
|
165
|
+
export function Layout({ children }) {
|
|
166
|
+
return (
|
|
167
|
+
<div class="layout">
|
|
168
|
+
<Nav />
|
|
169
|
+
<main class="content">{children}</main>
|
|
170
|
+
<footer class="footer">
|
|
171
|
+
<p>Built with What</p>
|
|
172
|
+
</footer>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
`);
|
|
177
|
+
|
|
178
|
+
// --- src/components/nav.jsx ---
|
|
179
|
+
writeFileSync(join(root, 'src/components/nav.jsx'), `import { Link } from 'what-framework/router';
|
|
180
|
+
|
|
181
|
+
export function Nav() {
|
|
182
|
+
return (
|
|
183
|
+
<nav class="nav">
|
|
184
|
+
<a href="/" class="nav-logo">What</a>
|
|
185
|
+
<div class="nav-links">
|
|
186
|
+
<Link href="/">Home</Link>
|
|
187
|
+
<Link href="/about">About</Link>
|
|
188
|
+
</div>
|
|
189
|
+
</nav>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
`);
|
|
193
|
+
|
|
194
|
+
// --- src/pages/index.jsx ---
|
|
195
|
+
writeFileSync(join(root, 'src/pages/index.jsx'), `import { useState } from 'what-framework';
|
|
196
|
+
|
|
197
|
+
export function Home() {
|
|
198
|
+
const [count, setCount] = useState(0);
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<div class="page home">
|
|
202
|
+
<h1>Welcome to What</h1>
|
|
203
|
+
<p>The closest framework to vanilla JS.</p>
|
|
204
|
+
<div class="counter">
|
|
205
|
+
<button onClick={() => setCount(c => c - 1)}>-</button>
|
|
206
|
+
<span class="count">{count}</span>
|
|
207
|
+
<button onClick={() => setCount(c => c + 1)}>+</button>
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export default Home;
|
|
214
|
+
`);
|
|
215
|
+
|
|
216
|
+
// --- src/pages/about.jsx ---
|
|
217
|
+
writeFileSync(join(root, 'src/pages/about.jsx'), `export function About() {
|
|
218
|
+
return (
|
|
219
|
+
<div class="page about">
|
|
220
|
+
<h1>About What</h1>
|
|
221
|
+
<p>What is a vanilla JS framework that gives you:</p>
|
|
222
|
+
<ul>
|
|
223
|
+
<li>Fine-grained reactivity (signals)</li>
|
|
224
|
+
<li>Surgical DOM updates (no virtual DOM diffing)</li>
|
|
225
|
+
<li>Islands architecture (ship zero JS by default)</li>
|
|
226
|
+
<li>File-based routing</li>
|
|
227
|
+
<li>SSR + SSG + client rendering</li>
|
|
228
|
+
<li>React-familiar hooks API</li>
|
|
229
|
+
</ul>
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export default About;
|
|
235
|
+
`);
|
|
236
|
+
|
|
237
|
+
} else {
|
|
238
|
+
// ==========================================================================
|
|
239
|
+
// Vanilla h() templates
|
|
240
|
+
// ==========================================================================
|
|
241
|
+
|
|
82
242
|
// --- src/app.js ---
|
|
83
|
-
writeFileSync(join(root, 'src/app.js'), `import { h, mount, signal } from 'what';
|
|
84
|
-
import { Router, Link, defineRoutes } from 'what/router';
|
|
243
|
+
writeFileSync(join(root, 'src/app.js'), `import { h, mount, signal } from 'what-framework';
|
|
244
|
+
import { Router, Link, defineRoutes } from 'what-framework/router';
|
|
85
245
|
import { Layout } from './layouts/main.js';
|
|
86
246
|
import { Home } from './pages/index.js';
|
|
87
247
|
import { About } from './pages/about.js';
|
|
@@ -107,8 +267,8 @@ mount(h(App), '#app');
|
|
|
107
267
|
`);
|
|
108
268
|
|
|
109
269
|
// --- src/layouts/main.js ---
|
|
110
|
-
writeFileSync(join(root, 'src/layouts/main.js'), `import { h } from 'what';
|
|
111
|
-
import { Link } from 'what/router';
|
|
270
|
+
writeFileSync(join(root, 'src/layouts/main.js'), `import { h } from 'what-framework';
|
|
271
|
+
import { Link } from 'what-framework/router';
|
|
112
272
|
import { Nav } from '../components/nav.js';
|
|
113
273
|
|
|
114
274
|
export function Layout({ children }) {
|
|
@@ -123,8 +283,8 @@ export function Layout({ children }) {
|
|
|
123
283
|
`);
|
|
124
284
|
|
|
125
285
|
// --- src/components/nav.js ---
|
|
126
|
-
writeFileSync(join(root, 'src/components/nav.js'), `import { h } from 'what';
|
|
127
|
-
import { Link } from 'what/router';
|
|
286
|
+
writeFileSync(join(root, 'src/components/nav.js'), `import { h } from 'what-framework';
|
|
287
|
+
import { Link } from 'what-framework/router';
|
|
128
288
|
|
|
129
289
|
export function Nav() {
|
|
130
290
|
return h('nav', { class: 'nav' },
|
|
@@ -138,7 +298,7 @@ export function Nav() {
|
|
|
138
298
|
`);
|
|
139
299
|
|
|
140
300
|
// --- src/pages/index.js ---
|
|
141
|
-
writeFileSync(join(root, 'src/pages/index.js'), `import { h, useState } from 'what';
|
|
301
|
+
writeFileSync(join(root, 'src/pages/index.js'), `import { h, useState } from 'what-framework';
|
|
142
302
|
|
|
143
303
|
export function Home() {
|
|
144
304
|
const [count, setCount] = useState(0);
|
|
@@ -158,7 +318,7 @@ export default Home;
|
|
|
158
318
|
`);
|
|
159
319
|
|
|
160
320
|
// --- src/pages/about.js ---
|
|
161
|
-
writeFileSync(join(root, 'src/pages/about.js'), `import { h } from 'what';
|
|
321
|
+
writeFileSync(join(root, 'src/pages/about.js'), `import { h } from 'what-framework';
|
|
162
322
|
|
|
163
323
|
export function About() {
|
|
164
324
|
return h('div', { class: 'page about' },
|
|
@@ -178,6 +338,8 @@ export function About() {
|
|
|
178
338
|
export default About;
|
|
179
339
|
`);
|
|
180
340
|
|
|
341
|
+
} // end vanilla mode
|
|
342
|
+
|
|
181
343
|
// --- public/styles.css ---
|
|
182
344
|
writeFileSync(join(root, 'public/styles.css'), `* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
183
345
|
|
|
@@ -222,7 +384,78 @@ li { margin-bottom: 0.25rem; }
|
|
|
222
384
|
.not-found h1 { font-size: 6rem; color: #ddd; }
|
|
223
385
|
`);
|
|
224
386
|
|
|
387
|
+
// --- README.md ---
|
|
388
|
+
const jsxNote = useJSX
|
|
389
|
+
? `This project uses **JSX** syntax, compiled by \`what-compiler\` via the Vite plugin.
|
|
390
|
+
|
|
391
|
+
To switch to vanilla \`h()\` calls instead, re-create with:
|
|
392
|
+
\`\`\`
|
|
393
|
+
npm create what@latest ${name} --vanilla
|
|
394
|
+
\`\`\``
|
|
395
|
+
: `This project uses the vanilla **h()** API for building components.
|
|
396
|
+
|
|
397
|
+
To use JSX syntax instead (recommended), re-create with:
|
|
398
|
+
\`\`\`
|
|
399
|
+
npm create what@latest ${name}
|
|
400
|
+
\`\`\``;
|
|
401
|
+
|
|
402
|
+
writeFileSync(join(root, 'README.md'), `# ${name}
|
|
403
|
+
|
|
404
|
+
A [What Framework](https://github.com/aspect/what-fw) project.
|
|
405
|
+
|
|
406
|
+
## Authoring Mode
|
|
407
|
+
|
|
408
|
+
${jsxNote}
|
|
409
|
+
|
|
410
|
+
## Getting Started
|
|
411
|
+
|
|
412
|
+
\`\`\`bash
|
|
413
|
+
cd ${name}
|
|
414
|
+
npm install
|
|
415
|
+
npm run dev
|
|
416
|
+
\`\`\`
|
|
417
|
+
|
|
418
|
+
## Scripts
|
|
419
|
+
|
|
420
|
+
| Command | Description |
|
|
421
|
+
| --------------- | ------------------------------------ |
|
|
422
|
+
| \`npm run dev\` | Start development server |
|
|
423
|
+
| \`npm run build\` | Build for production |
|
|
424
|
+
| \`npm run preview\`| Preview production build |
|
|
425
|
+
| \`npm run generate\`| Static site generation (SSG) |
|
|
426
|
+
|
|
427
|
+
## Project Structure
|
|
428
|
+
|
|
429
|
+
\`\`\`
|
|
430
|
+
${name}/
|
|
431
|
+
src/
|
|
432
|
+
pages/ # File-based routes
|
|
433
|
+
components/ # Shared components
|
|
434
|
+
layouts/ # Page layouts
|
|
435
|
+
islands/ # Hydrated interactive islands
|
|
436
|
+
${useJSX ? ' app.jsx # App entry point (JSX)' : ' app.js # App entry point'}
|
|
437
|
+
public/ # Static assets
|
|
438
|
+
index.html # HTML shell (Vite entry)
|
|
439
|
+
what.config.js # Framework configuration
|
|
440
|
+
${useJSX ? ' vite.config.js # Vite + what-compiler plugin\n' : ''} package.json
|
|
441
|
+
\`\`\`
|
|
442
|
+
|
|
443
|
+
## Learn More
|
|
444
|
+
|
|
445
|
+
- [What Framework docs](https://github.com/aspect/what-fw)
|
|
446
|
+
- JSX authoring: uses \`what-compiler\` to transform JSX to optimized DOM calls
|
|
447
|
+
- Vanilla authoring: use \`h(tag, props, ...children)\` directly -- zero build step needed
|
|
448
|
+
`);
|
|
449
|
+
|
|
450
|
+
// --- Done ---
|
|
225
451
|
console.log(` Done! Next steps:\n`);
|
|
226
452
|
console.log(` cd ${name}`);
|
|
227
453
|
console.log(` npm install`);
|
|
228
454
|
console.log(` npm run dev\n`);
|
|
455
|
+
|
|
456
|
+
if (useJSX) {
|
|
457
|
+
console.log(` JSX mode enabled. Components use .jsx extensions.`);
|
|
458
|
+
console.log(` The what-compiler Vite plugin handles JSX transformation.\n`);
|
|
459
|
+
} else {
|
|
460
|
+
console.log(` Vanilla mode. Components use h() calls -- no compiler needed.\n`);
|
|
461
|
+
}
|