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