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.
Files changed (2) hide show
  1. package/index.js +257 -24
  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,49 @@ 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
+ '@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
- 'what': '^0.1.0',
45
- 'what-cli': '^0.1.0',
46
- },
47
- }, null, 2) + '\n');
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
- // --- src/index.html ---
67
- writeFileSync(join(root, 'src/index.html'), `<!DOCTYPE html>
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="/app.js"></script>
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-what",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Scaffold a new What Framework project",
5
5
  "type": "module",
6
6
  "bin": {