create-what 0.3.0 → 0.4.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.
- package/index.js +122 -392
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -1,94 +1,70 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// create-what
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// create-what
|
|
4
|
+
// Canonical scaffold for What Framework projects.
|
|
6
5
|
// Usage:
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// npm create what@latest my-app --vanilla # vanilla h() project
|
|
6
|
+
// npx create-what my-app
|
|
7
|
+
// npx create-what my-app --vanilla
|
|
10
8
|
|
|
11
|
-
import { mkdirSync, writeFileSync, existsSync } from 'fs';
|
|
12
|
-
import { join } from 'path';
|
|
9
|
+
import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
13
11
|
|
|
14
|
-
// --- Parse CLI arguments ---
|
|
15
12
|
const args = process.argv.slice(2);
|
|
16
13
|
const flags = args.filter(a => a.startsWith('-'));
|
|
17
14
|
const positional = args.filter(a => !a.startsWith('-'));
|
|
18
15
|
|
|
19
|
-
const
|
|
20
|
-
const template = positional[1] || 'default'; // default | minimal | full
|
|
21
|
-
|
|
22
|
-
// JSX is the default; opt out with --no-jsx or --vanilla
|
|
16
|
+
const projectName = positional[0] || 'my-what-app';
|
|
23
17
|
const useJSX = !flags.includes('--no-jsx') && !flags.includes('--vanilla');
|
|
24
18
|
|
|
25
|
-
const
|
|
26
|
-
const root = join(cwd, name);
|
|
19
|
+
const root = join(process.cwd(), projectName);
|
|
27
20
|
|
|
28
21
|
if (existsSync(root)) {
|
|
29
|
-
console.error(`\
|
|
22
|
+
console.error(`\nError: "${projectName}" already exists.`);
|
|
30
23
|
process.exit(1);
|
|
31
24
|
}
|
|
32
25
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const dirs = [
|
|
41
|
-
'src/pages',
|
|
42
|
-
'src/components',
|
|
43
|
-
'src/layouts',
|
|
44
|
-
'src/islands',
|
|
45
|
-
'public',
|
|
46
|
-
];
|
|
47
|
-
dirs.forEach(d => mkdirSync(join(root, d), { recursive: true }));
|
|
48
|
-
|
|
49
|
-
// --- .gitignore ---
|
|
50
|
-
writeFileSync(join(root, '.gitignore'), `node_modules
|
|
51
|
-
dist
|
|
52
|
-
.vite
|
|
53
|
-
.DS_Store
|
|
54
|
-
*.local
|
|
55
|
-
`);
|
|
26
|
+
mkdirSync(join(root, 'src'), { recursive: true });
|
|
27
|
+
mkdirSync(join(root, 'public'), { recursive: true });
|
|
28
|
+
|
|
29
|
+
const ext = useJSX ? 'jsx' : 'js';
|
|
30
|
+
const entry = `src/main.${ext}`;
|
|
31
|
+
|
|
32
|
+
writeFileSync(join(root, '.gitignore'), `node_modules\ndist\n.DS_Store\n`);
|
|
56
33
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
'what-framework': '^0.3.0',
|
|
60
|
-
'what-framework-cli': '^0.1.0',
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const pkgDevDeps = useJSX
|
|
64
|
-
? {
|
|
65
|
-
'what-compiler': '^0.3.0',
|
|
66
|
-
'@babel/core': '^7.23.0',
|
|
67
|
-
'vite': '^5.0.0',
|
|
68
|
-
}
|
|
69
|
-
: {};
|
|
70
|
-
|
|
71
|
-
const pkg = {
|
|
72
|
-
name,
|
|
34
|
+
writeFileSync(join(root, 'package.json'), JSON.stringify({
|
|
35
|
+
name: projectName,
|
|
73
36
|
private: true,
|
|
74
|
-
version: '0.0
|
|
37
|
+
version: '0.1.0',
|
|
75
38
|
type: 'module',
|
|
76
39
|
scripts: {
|
|
77
|
-
dev:
|
|
78
|
-
build:
|
|
79
|
-
preview:
|
|
80
|
-
generate: 'what generate',
|
|
40
|
+
dev: 'vite',
|
|
41
|
+
build: 'vite build',
|
|
42
|
+
preview: 'vite preview',
|
|
81
43
|
},
|
|
82
|
-
dependencies:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
44
|
+
dependencies: {
|
|
45
|
+
'what-framework': '^0.4.2',
|
|
46
|
+
},
|
|
47
|
+
devDependencies: {
|
|
48
|
+
vite: '^5.4.0',
|
|
49
|
+
...(useJSX ? { 'what-compiler': '^0.4.2' } : {}),
|
|
50
|
+
},
|
|
51
|
+
}, null, 2) + '\n');
|
|
88
52
|
|
|
89
|
-
writeFileSync(join(root, '
|
|
53
|
+
writeFileSync(join(root, 'index.html'), `<!doctype html>
|
|
54
|
+
<html lang="en">
|
|
55
|
+
<head>
|
|
56
|
+
<meta charset="UTF-8" />
|
|
57
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
58
|
+
<title>${projectName}</title>
|
|
59
|
+
<link rel="stylesheet" href="/src/styles.css" />
|
|
60
|
+
</head>
|
|
61
|
+
<body>
|
|
62
|
+
<div id="app"></div>
|
|
63
|
+
<script type="module" src="/${entry}"></script>
|
|
64
|
+
</body>
|
|
65
|
+
</html>
|
|
66
|
+
`);
|
|
90
67
|
|
|
91
|
-
// --- vite.config.js (JSX only) ---
|
|
92
68
|
if (useJSX) {
|
|
93
69
|
writeFileSync(join(root, 'vite.config.js'), `import { defineConfig } from 'vite';
|
|
94
70
|
import what from 'what-compiler/vite';
|
|
@@ -97,376 +73,130 @@ export default defineConfig({
|
|
|
97
73
|
plugins: [what()],
|
|
98
74
|
});
|
|
99
75
|
`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// --- what.config.js ---
|
|
103
|
-
writeFileSync(join(root, 'what.config.js'), `// What Framework Configuration
|
|
104
|
-
export default {
|
|
105
|
-
// Rendering mode: 'static' | 'server' | 'client' | 'hybrid'
|
|
106
|
-
mode: 'hybrid',
|
|
107
|
-
|
|
108
|
-
// Pages directory (file-based routing)
|
|
109
|
-
pagesDir: 'src/pages',
|
|
110
|
-
|
|
111
|
-
// Build output
|
|
112
|
-
outDir: 'dist',
|
|
113
|
-
|
|
114
|
-
// Islands: components that hydrate independently
|
|
115
|
-
islands: true,
|
|
116
|
-
};
|
|
117
|
-
`);
|
|
118
76
|
|
|
119
|
-
|
|
120
|
-
const appScript = useJSX ? '/src/app.jsx' : '/src/app.js';
|
|
121
|
-
writeFileSync(join(root, 'index.html'), `<!DOCTYPE html>
|
|
122
|
-
<html lang="en">
|
|
123
|
-
<head>
|
|
124
|
-
<meta charset="UTF-8">
|
|
125
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
126
|
-
<title>${name}</title>
|
|
127
|
-
<link rel="stylesheet" href="/styles.css">
|
|
128
|
-
</head>
|
|
129
|
-
<body>
|
|
130
|
-
<div id="app"></div>
|
|
131
|
-
<script type="module" src="${appScript}"></script>
|
|
132
|
-
</body>
|
|
133
|
-
</html>
|
|
134
|
-
`);
|
|
135
|
-
|
|
136
|
-
// ==========================================================================
|
|
137
|
-
// JSX templates
|
|
138
|
-
// ==========================================================================
|
|
139
|
-
if (useJSX) {
|
|
140
|
-
|
|
141
|
-
// --- src/app.jsx ---
|
|
142
|
-
writeFileSync(join(root, 'src/app.jsx'), `import { mount } from 'what-framework';
|
|
143
|
-
import { Router, Link, defineRoutes } from 'what-framework/router';
|
|
144
|
-
import { Layout } from './layouts/main.jsx';
|
|
145
|
-
import { Home } from './pages/index.jsx';
|
|
146
|
-
import { About } from './pages/about.jsx';
|
|
147
|
-
|
|
148
|
-
const routes = defineRoutes({
|
|
149
|
-
'/': { component: Home, layout: Layout },
|
|
150
|
-
'/about': { component: About, layout: Layout },
|
|
151
|
-
});
|
|
77
|
+
writeFileSync(join(root, 'src', 'main.jsx'), `import { mount, useSignal } from 'what-framework';
|
|
152
78
|
|
|
153
79
|
function App() {
|
|
154
|
-
|
|
155
|
-
}
|
|
80
|
+
const count = useSignal(0);
|
|
156
81
|
|
|
157
|
-
function NotFound() {
|
|
158
82
|
return (
|
|
159
|
-
<
|
|
160
|
-
<h1>
|
|
161
|
-
<p>
|
|
162
|
-
|
|
163
|
-
|
|
83
|
+
<main className="app-shell">
|
|
84
|
+
<h1>What Framework</h1>
|
|
85
|
+
<p>Compiler-first JSX, React-familiar authoring.</p>
|
|
86
|
+
|
|
87
|
+
<section className="counter">
|
|
88
|
+
<button onClick={() => count.set(c => c - 1)}>-</button>
|
|
89
|
+
<output>{count()}</output>
|
|
90
|
+
<button onClick={() => count.set(c => c + 1)}>+</button>
|
|
91
|
+
</section>
|
|
92
|
+
</main>
|
|
164
93
|
);
|
|
165
94
|
}
|
|
166
95
|
|
|
167
96
|
mount(<App />, '#app');
|
|
168
97
|
`);
|
|
98
|
+
} else {
|
|
99
|
+
writeFileSync(join(root, 'vite.config.js'), `import { defineConfig } from 'vite';
|
|
169
100
|
|
|
170
|
-
|
|
171
|
-
writeFileSync(join(root, 'src/layouts/main.jsx'), `import { Nav } from '../components/nav.jsx';
|
|
172
|
-
|
|
173
|
-
export function Layout({ children }) {
|
|
174
|
-
return (
|
|
175
|
-
<div class="layout">
|
|
176
|
-
<Nav />
|
|
177
|
-
<main class="content">{children}</main>
|
|
178
|
-
<footer class="footer">
|
|
179
|
-
<p>Built with What</p>
|
|
180
|
-
</footer>
|
|
181
|
-
</div>
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
`);
|
|
185
|
-
|
|
186
|
-
// --- src/components/nav.jsx ---
|
|
187
|
-
writeFileSync(join(root, 'src/components/nav.jsx'), `import { Link } from 'what-framework/router';
|
|
188
|
-
|
|
189
|
-
export function Nav() {
|
|
190
|
-
return (
|
|
191
|
-
<nav class="nav">
|
|
192
|
-
<a href="/" class="nav-logo">What</a>
|
|
193
|
-
<div class="nav-links">
|
|
194
|
-
<Link href="/">Home</Link>
|
|
195
|
-
<Link href="/about">About</Link>
|
|
196
|
-
</div>
|
|
197
|
-
</nav>
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
`);
|
|
201
|
-
|
|
202
|
-
// --- src/pages/index.jsx ---
|
|
203
|
-
writeFileSync(join(root, 'src/pages/index.jsx'), `import { useState } from 'what-framework';
|
|
204
|
-
|
|
205
|
-
export function Home() {
|
|
206
|
-
const [count, setCount] = useState(0);
|
|
207
|
-
|
|
208
|
-
return (
|
|
209
|
-
<div class="page home">
|
|
210
|
-
<h1>Welcome to What</h1>
|
|
211
|
-
<p>The closest framework to vanilla JS.</p>
|
|
212
|
-
<div class="counter">
|
|
213
|
-
<button onClick={() => setCount(c => c - 1)}>-</button>
|
|
214
|
-
<span class="count">{count}</span>
|
|
215
|
-
<button onClick={() => setCount(c => c + 1)}>+</button>
|
|
216
|
-
</div>
|
|
217
|
-
</div>
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
export default Home;
|
|
101
|
+
export default defineConfig({});
|
|
222
102
|
`);
|
|
223
103
|
|
|
224
|
-
|
|
225
|
-
writeFileSync(join(root, 'src/pages/about.jsx'), `export function About() {
|
|
226
|
-
return (
|
|
227
|
-
<div class="page about">
|
|
228
|
-
<h1>About What</h1>
|
|
229
|
-
<p>What is a vanilla JS framework that gives you:</p>
|
|
230
|
-
<ul>
|
|
231
|
-
<li>Fine-grained reactivity (signals)</li>
|
|
232
|
-
<li>Surgical DOM updates (no virtual DOM diffing)</li>
|
|
233
|
-
<li>Islands architecture (ship zero JS by default)</li>
|
|
234
|
-
<li>File-based routing</li>
|
|
235
|
-
<li>SSR + SSG + client rendering</li>
|
|
236
|
-
<li>React-familiar hooks API</li>
|
|
237
|
-
</ul>
|
|
238
|
-
</div>
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export default About;
|
|
243
|
-
`);
|
|
244
|
-
|
|
245
|
-
} else {
|
|
246
|
-
// ==========================================================================
|
|
247
|
-
// Vanilla h() templates
|
|
248
|
-
// ==========================================================================
|
|
249
|
-
|
|
250
|
-
// --- src/app.js ---
|
|
251
|
-
writeFileSync(join(root, 'src/app.js'), `import { h, mount, signal } from 'what-framework';
|
|
252
|
-
import { Router, Link, defineRoutes } from 'what-framework/router';
|
|
253
|
-
import { Layout } from './layouts/main.js';
|
|
254
|
-
import { Home } from './pages/index.js';
|
|
255
|
-
import { About } from './pages/about.js';
|
|
256
|
-
|
|
257
|
-
const routes = defineRoutes({
|
|
258
|
-
'/': { component: Home, layout: Layout },
|
|
259
|
-
'/about': { component: About, layout: Layout },
|
|
260
|
-
});
|
|
104
|
+
writeFileSync(join(root, 'src', 'main.js'), `import { h, mount, signal } from 'what-framework';
|
|
261
105
|
|
|
262
106
|
function App() {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
h('
|
|
269
|
-
|
|
270
|
-
|
|
107
|
+
const count = signal(0);
|
|
108
|
+
|
|
109
|
+
return h('main', { class: 'app-shell' },
|
|
110
|
+
h('h1', null, 'What Framework'),
|
|
111
|
+
h('p', null, 'Runtime h() path (advanced).'),
|
|
112
|
+
h('section', { class: 'counter' },
|
|
113
|
+
h('button', { onClick: () => count.set(c => c - 1) }, '-'),
|
|
114
|
+
h('output', null, () => count()),
|
|
115
|
+
h('button', { onClick: () => count.set(c => c + 1) }, '+'),
|
|
116
|
+
),
|
|
271
117
|
);
|
|
272
118
|
}
|
|
273
119
|
|
|
274
120
|
mount(h(App), '#app');
|
|
275
121
|
`);
|
|
276
|
-
|
|
277
|
-
// --- src/layouts/main.js ---
|
|
278
|
-
writeFileSync(join(root, 'src/layouts/main.js'), `import { h } from 'what-framework';
|
|
279
|
-
import { Link } from 'what-framework/router';
|
|
280
|
-
import { Nav } from '../components/nav.js';
|
|
281
|
-
|
|
282
|
-
export function Layout({ children }) {
|
|
283
|
-
return h('div', { class: 'layout' },
|
|
284
|
-
h(Nav),
|
|
285
|
-
h('main', { class: 'content' }, children),
|
|
286
|
-
h('footer', { class: 'footer' },
|
|
287
|
-
h('p', null, 'Built with What'),
|
|
288
|
-
),
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
`);
|
|
292
|
-
|
|
293
|
-
// --- src/components/nav.js ---
|
|
294
|
-
writeFileSync(join(root, 'src/components/nav.js'), `import { h } from 'what-framework';
|
|
295
|
-
import { Link } from 'what-framework/router';
|
|
296
|
-
|
|
297
|
-
export function Nav() {
|
|
298
|
-
return h('nav', { class: 'nav' },
|
|
299
|
-
h('a', { href: '/', class: 'nav-logo' }, 'What'),
|
|
300
|
-
h('div', { class: 'nav-links' },
|
|
301
|
-
h(Link, { href: '/' }, 'Home'),
|
|
302
|
-
h(Link, { href: '/about' }, 'About'),
|
|
303
|
-
),
|
|
304
|
-
);
|
|
305
122
|
}
|
|
306
|
-
`);
|
|
307
|
-
|
|
308
|
-
// --- src/pages/index.js ---
|
|
309
|
-
writeFileSync(join(root, 'src/pages/index.js'), `import { h, useState } from 'what-framework';
|
|
310
|
-
|
|
311
|
-
export function Home() {
|
|
312
|
-
const [count, setCount] = useState(0);
|
|
313
123
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
h('div', { class: 'counter' },
|
|
318
|
-
h('button', { onClick: () => setCount(c => c - 1) }, '-'),
|
|
319
|
-
h('span', { class: 'count' }, count),
|
|
320
|
-
h('button', { onClick: () => setCount(c => c + 1) }, '+'),
|
|
321
|
-
),
|
|
322
|
-
);
|
|
124
|
+
writeFileSync(join(root, 'src', 'styles.css'), `:root {
|
|
125
|
+
color-scheme: light;
|
|
126
|
+
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif;
|
|
323
127
|
}
|
|
324
128
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
// --- src/pages/about.js ---
|
|
329
|
-
writeFileSync(join(root, 'src/pages/about.js'), `import { h } from 'what-framework';
|
|
330
|
-
|
|
331
|
-
export function About() {
|
|
332
|
-
return h('div', { class: 'page about' },
|
|
333
|
-
h('h1', null, 'About What'),
|
|
334
|
-
h('p', null, 'What is a vanilla JS framework that gives you:'),
|
|
335
|
-
h('ul', null,
|
|
336
|
-
h('li', null, 'Fine-grained reactivity (signals)'),
|
|
337
|
-
h('li', null, 'Surgical DOM updates (no virtual DOM diffing)'),
|
|
338
|
-
h('li', null, 'Islands architecture (ship zero JS by default)'),
|
|
339
|
-
h('li', null, 'File-based routing'),
|
|
340
|
-
h('li', null, 'SSR + SSG + client rendering'),
|
|
341
|
-
h('li', null, 'React-familiar hooks API'),
|
|
342
|
-
),
|
|
343
|
-
);
|
|
129
|
+
* {
|
|
130
|
+
box-sizing: border-box;
|
|
344
131
|
}
|
|
345
132
|
|
|
346
|
-
export default About;
|
|
347
|
-
`);
|
|
348
|
-
|
|
349
|
-
} // end vanilla mode
|
|
350
|
-
|
|
351
|
-
// --- public/styles.css ---
|
|
352
|
-
writeFileSync(join(root, 'public/styles.css'), `* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
353
|
-
|
|
354
133
|
body {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
134
|
+
margin: 0;
|
|
135
|
+
min-height: 100vh;
|
|
136
|
+
display: grid;
|
|
137
|
+
place-items: center;
|
|
138
|
+
background: #f4f6fb;
|
|
139
|
+
color: #0f172a;
|
|
359
140
|
}
|
|
360
141
|
|
|
361
|
-
.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
padding:
|
|
142
|
+
.app-shell {
|
|
143
|
+
width: min(560px, calc(100vw - 2rem));
|
|
144
|
+
background: #ffffff;
|
|
145
|
+
border: 1px solid #dbe2ee;
|
|
146
|
+
border-radius: 16px;
|
|
147
|
+
padding: 2rem;
|
|
148
|
+
box-shadow: 0 16px 40px rgba(15, 23, 42, 0.06);
|
|
367
149
|
}
|
|
368
|
-
.nav-logo { color: white; text-decoration: none; font-weight: 700; font-size: 1.25rem; }
|
|
369
|
-
.nav-links { display: flex; gap: 1rem; }
|
|
370
|
-
.nav-links a { color: #a0a0c0; text-decoration: none; transition: color 0.2s; }
|
|
371
|
-
.nav-links a:hover { color: white; }
|
|
372
|
-
|
|
373
|
-
.footer { padding: 1rem 2rem; text-align: center; color: #666; font-size: 0.875rem; }
|
|
374
|
-
|
|
375
|
-
h1 { font-size: 2.5rem; margin-bottom: 1rem; }
|
|
376
|
-
p { margin-bottom: 1rem; }
|
|
377
150
|
|
|
378
151
|
.counter {
|
|
379
|
-
|
|
152
|
+
margin-top: 1rem;
|
|
153
|
+
display: inline-flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
gap: 0.75rem;
|
|
380
156
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
157
|
+
|
|
158
|
+
button {
|
|
159
|
+
border: 1px solid #9aa7bb;
|
|
160
|
+
background: #ffffff;
|
|
161
|
+
color: #0f172a;
|
|
162
|
+
width: 2.25rem;
|
|
163
|
+
height: 2.25rem;
|
|
164
|
+
border-radius: 10px;
|
|
165
|
+
cursor: pointer;
|
|
384
166
|
}
|
|
385
|
-
.counter button:hover { background: #1a1a2e; color: white; }
|
|
386
|
-
.count { font-size: 2rem; font-weight: 700; min-width: 3rem; text-align: center; }
|
|
387
167
|
|
|
388
|
-
|
|
389
|
-
|
|
168
|
+
button:hover {
|
|
169
|
+
border-color: #2563eb;
|
|
170
|
+
}
|
|
390
171
|
|
|
391
|
-
|
|
392
|
-
|
|
172
|
+
output {
|
|
173
|
+
min-width: 2ch;
|
|
174
|
+
text-align: center;
|
|
175
|
+
font-weight: 700;
|
|
176
|
+
}
|
|
393
177
|
`);
|
|
394
178
|
|
|
395
|
-
|
|
396
|
-
const jsxNote = useJSX
|
|
397
|
-
? `This project uses **JSX** syntax, compiled by \`what-compiler\` via the Vite plugin.
|
|
398
|
-
|
|
399
|
-
To switch to vanilla \`h()\` calls instead, re-create with:
|
|
400
|
-
\`\`\`
|
|
401
|
-
npm create what@latest ${name} --vanilla
|
|
402
|
-
\`\`\``
|
|
403
|
-
: `This project uses the vanilla **h()** API for building components.
|
|
404
|
-
|
|
405
|
-
To use JSX syntax instead (recommended), re-create with:
|
|
406
|
-
\`\`\`
|
|
407
|
-
npm create what@latest ${name}
|
|
408
|
-
\`\`\``;
|
|
409
|
-
|
|
410
|
-
writeFileSync(join(root, 'README.md'), `# ${name}
|
|
411
|
-
|
|
412
|
-
A [What Framework](https://github.com/aspect/what-fw) project.
|
|
179
|
+
writeFileSync(join(root, 'README.md'), `# ${projectName}
|
|
413
180
|
|
|
414
|
-
##
|
|
415
|
-
|
|
416
|
-
${jsxNote}
|
|
417
|
-
|
|
418
|
-
## Getting Started
|
|
181
|
+
## Run
|
|
419
182
|
|
|
420
183
|
\`\`\`bash
|
|
421
|
-
cd ${name}
|
|
422
184
|
npm install
|
|
423
185
|
npm run dev
|
|
424
186
|
\`\`\`
|
|
425
187
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
| Command | Description |
|
|
429
|
-
| --------------- | ------------------------------------ |
|
|
430
|
-
| \`npm run dev\` | Start development server |
|
|
431
|
-
| \`npm run build\` | Build for production |
|
|
432
|
-
| \`npm run preview\`| Preview production build |
|
|
433
|
-
| \`npm run generate\`| Static site generation (SSG) |
|
|
434
|
-
|
|
435
|
-
## Project Structure
|
|
436
|
-
|
|
437
|
-
\`\`\`
|
|
438
|
-
${name}/
|
|
439
|
-
src/
|
|
440
|
-
pages/ # File-based routes
|
|
441
|
-
components/ # Shared components
|
|
442
|
-
layouts/ # Page layouts
|
|
443
|
-
islands/ # Hydrated interactive islands
|
|
444
|
-
${useJSX ? ' app.jsx # App entry point (JSX)' : ' app.js # App entry point'}
|
|
445
|
-
public/ # Static assets
|
|
446
|
-
index.html # HTML shell (Vite entry)
|
|
447
|
-
what.config.js # Framework configuration
|
|
448
|
-
${useJSX ? ' vite.config.js # Vite + what-compiler plugin\n' : ''} package.json
|
|
449
|
-
\`\`\`
|
|
188
|
+
Open [http://localhost:5173](http://localhost:5173).
|
|
450
189
|
|
|
451
|
-
##
|
|
190
|
+
## Notes
|
|
452
191
|
|
|
453
|
-
-
|
|
454
|
-
- JSX
|
|
455
|
-
-
|
|
192
|
+
- Canonical package name is \`what-framework\`.
|
|
193
|
+
- JSX path is compiler-first and recommended.
|
|
194
|
+
- Runtime \`h()\` path is available with \`--vanilla\`.
|
|
195
|
+
- Event handlers accept both \`onClick\` and \`onclick\`; docs and templates use \`onClick\`.
|
|
456
196
|
`);
|
|
457
197
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
console.log(
|
|
462
|
-
console.log(
|
|
463
|
-
console.log(` npm install`);
|
|
464
|
-
console.log(` npm run dev\n`);
|
|
465
|
-
|
|
466
|
-
if (useJSX) {
|
|
467
|
-
console.log(` JSX mode enabled. Components use .jsx extensions.`);
|
|
468
|
-
console.log(` The what-compiler Vite plugin compiles JSX to h() calls.`);
|
|
469
|
-
console.log(` Open http://localhost:5173 after running dev.\n`);
|
|
470
|
-
} else {
|
|
471
|
-
console.log(` Vanilla mode. Components use h() calls -- no compiler needed.\n`);
|
|
472
|
-
}
|
|
198
|
+
console.log(`\nCreated ${projectName} (${useJSX ? 'jsx' : 'vanilla'} mode).`);
|
|
199
|
+
console.log('Next steps:');
|
|
200
|
+
console.log(` cd ${projectName}`);
|
|
201
|
+
console.log(' npm install');
|
|
202
|
+
console.log(' npm run dev\n');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-what",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Scaffold a new What Framework project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
|
-
"url": "https://github.com/aspect/what-fw"
|
|
24
|
+
"url": "git+https://github.com/aspect/what-fw.git"
|
|
25
25
|
}
|
|
26
26
|
}
|