create-what 0.1.1
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 +228 -0
- package/package.json +26 -0
package/index.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// create-what: npm create what@latest my-app
|
|
4
|
+
// Scaffolds a new What framework project with sensible defaults.
|
|
5
|
+
|
|
6
|
+
import { mkdirSync, writeFileSync, existsSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
|
|
9
|
+
const name = process.argv[2] || 'my-what-app';
|
|
10
|
+
const template = process.argv[3] || 'default'; // default | minimal | full
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
const root = join(cwd, name);
|
|
13
|
+
|
|
14
|
+
if (existsSync(root)) {
|
|
15
|
+
console.error(`\n Error: "${name}" already exists.\n`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log(`\n Creating ${name} with template: ${template}\n`);
|
|
20
|
+
|
|
21
|
+
// Create directory structure
|
|
22
|
+
const dirs = [
|
|
23
|
+
'src/pages',
|
|
24
|
+
'src/components',
|
|
25
|
+
'src/layouts',
|
|
26
|
+
'src/islands',
|
|
27
|
+
'public',
|
|
28
|
+
];
|
|
29
|
+
dirs.forEach(d => mkdirSync(join(root, d), { recursive: true }));
|
|
30
|
+
|
|
31
|
+
// --- package.json ---
|
|
32
|
+
writeFileSync(join(root, 'package.json'), JSON.stringify({
|
|
33
|
+
name,
|
|
34
|
+
private: true,
|
|
35
|
+
version: '0.0.1',
|
|
36
|
+
type: 'module',
|
|
37
|
+
scripts: {
|
|
38
|
+
dev: 'what dev',
|
|
39
|
+
build: 'what build',
|
|
40
|
+
preview: 'what preview',
|
|
41
|
+
generate: 'what generate',
|
|
42
|
+
},
|
|
43
|
+
dependencies: {
|
|
44
|
+
'what': '^0.1.0',
|
|
45
|
+
'what-cli': '^0.1.0',
|
|
46
|
+
},
|
|
47
|
+
}, null, 2) + '\n');
|
|
48
|
+
|
|
49
|
+
// --- what.config.js ---
|
|
50
|
+
writeFileSync(join(root, 'what.config.js'), `// What Framework Configuration
|
|
51
|
+
export default {
|
|
52
|
+
// Rendering mode: 'static' | 'server' | 'client' | 'hybrid'
|
|
53
|
+
mode: 'hybrid',
|
|
54
|
+
|
|
55
|
+
// Pages directory (file-based routing)
|
|
56
|
+
pagesDir: 'src/pages',
|
|
57
|
+
|
|
58
|
+
// Build output
|
|
59
|
+
outDir: 'dist',
|
|
60
|
+
|
|
61
|
+
// Islands: components that hydrate independently
|
|
62
|
+
islands: true,
|
|
63
|
+
};
|
|
64
|
+
`);
|
|
65
|
+
|
|
66
|
+
// --- src/index.html ---
|
|
67
|
+
writeFileSync(join(root, 'src/index.html'), `<!DOCTYPE html>
|
|
68
|
+
<html lang="en">
|
|
69
|
+
<head>
|
|
70
|
+
<meta charset="UTF-8">
|
|
71
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
72
|
+
<title>${name}</title>
|
|
73
|
+
<link rel="stylesheet" href="/styles.css">
|
|
74
|
+
</head>
|
|
75
|
+
<body>
|
|
76
|
+
<div id="app"></div>
|
|
77
|
+
<script type="module" src="/app.js"></script>
|
|
78
|
+
</body>
|
|
79
|
+
</html>
|
|
80
|
+
`);
|
|
81
|
+
|
|
82
|
+
// --- src/app.js ---
|
|
83
|
+
writeFileSync(join(root, 'src/app.js'), `import { h, mount, signal } from 'what';
|
|
84
|
+
import { Router, Link, defineRoutes } from 'what/router';
|
|
85
|
+
import { Layout } from './layouts/main.js';
|
|
86
|
+
import { Home } from './pages/index.js';
|
|
87
|
+
import { About } from './pages/about.js';
|
|
88
|
+
|
|
89
|
+
const routes = defineRoutes({
|
|
90
|
+
'/': { component: Home, layout: Layout },
|
|
91
|
+
'/about': { component: About, layout: Layout },
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
function App() {
|
|
95
|
+
return h(Router, { routes, fallback: NotFound });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function NotFound() {
|
|
99
|
+
return h('div', { class: 'not-found' },
|
|
100
|
+
h('h1', null, '404'),
|
|
101
|
+
h('p', null, 'Page not found'),
|
|
102
|
+
h(Link, { href: '/' }, 'Go home'),
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
mount(h(App), '#app');
|
|
107
|
+
`);
|
|
108
|
+
|
|
109
|
+
// --- src/layouts/main.js ---
|
|
110
|
+
writeFileSync(join(root, 'src/layouts/main.js'), `import { h } from 'what';
|
|
111
|
+
import { Link } from 'what/router';
|
|
112
|
+
import { Nav } from '../components/nav.js';
|
|
113
|
+
|
|
114
|
+
export function Layout({ children }) {
|
|
115
|
+
return h('div', { class: 'layout' },
|
|
116
|
+
h(Nav),
|
|
117
|
+
h('main', { class: 'content' }, children),
|
|
118
|
+
h('footer', { class: 'footer' },
|
|
119
|
+
h('p', null, 'Built with What'),
|
|
120
|
+
),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
`);
|
|
124
|
+
|
|
125
|
+
// --- src/components/nav.js ---
|
|
126
|
+
writeFileSync(join(root, 'src/components/nav.js'), `import { h } from 'what';
|
|
127
|
+
import { Link } from 'what/router';
|
|
128
|
+
|
|
129
|
+
export function Nav() {
|
|
130
|
+
return h('nav', { class: 'nav' },
|
|
131
|
+
h('a', { href: '/', class: 'nav-logo' }, 'What'),
|
|
132
|
+
h('div', { class: 'nav-links' },
|
|
133
|
+
h(Link, { href: '/' }, 'Home'),
|
|
134
|
+
h(Link, { href: '/about' }, 'About'),
|
|
135
|
+
),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
`);
|
|
139
|
+
|
|
140
|
+
// --- src/pages/index.js ---
|
|
141
|
+
writeFileSync(join(root, 'src/pages/index.js'), `import { h, useState } from 'what';
|
|
142
|
+
|
|
143
|
+
export function Home() {
|
|
144
|
+
const [count, setCount] = useState(0);
|
|
145
|
+
|
|
146
|
+
return h('div', { class: 'page home' },
|
|
147
|
+
h('h1', null, 'Welcome to What'),
|
|
148
|
+
h('p', null, 'The closest framework to vanilla JS.'),
|
|
149
|
+
h('div', { class: 'counter' },
|
|
150
|
+
h('button', { onClick: () => setCount(c => c - 1) }, '-'),
|
|
151
|
+
h('span', { class: 'count' }, count),
|
|
152
|
+
h('button', { onClick: () => setCount(c => c + 1) }, '+'),
|
|
153
|
+
),
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export default Home;
|
|
158
|
+
`);
|
|
159
|
+
|
|
160
|
+
// --- src/pages/about.js ---
|
|
161
|
+
writeFileSync(join(root, 'src/pages/about.js'), `import { h } from 'what';
|
|
162
|
+
|
|
163
|
+
export function About() {
|
|
164
|
+
return h('div', { class: 'page about' },
|
|
165
|
+
h('h1', null, 'About What'),
|
|
166
|
+
h('p', null, 'What is a vanilla JS framework that gives you:'),
|
|
167
|
+
h('ul', null,
|
|
168
|
+
h('li', null, 'Fine-grained reactivity (signals)'),
|
|
169
|
+
h('li', null, 'Surgical DOM updates (no virtual DOM diffing)'),
|
|
170
|
+
h('li', null, 'Islands architecture (ship zero JS by default)'),
|
|
171
|
+
h('li', null, 'File-based routing'),
|
|
172
|
+
h('li', null, 'SSR + SSG + client rendering'),
|
|
173
|
+
h('li', null, 'React-familiar hooks API'),
|
|
174
|
+
),
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export default About;
|
|
179
|
+
`);
|
|
180
|
+
|
|
181
|
+
// --- public/styles.css ---
|
|
182
|
+
writeFileSync(join(root, 'public/styles.css'), `* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
183
|
+
|
|
184
|
+
body {
|
|
185
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
|
186
|
+
line-height: 1.6;
|
|
187
|
+
color: #1a1a2e;
|
|
188
|
+
background: #fafafa;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.layout { min-height: 100vh; display: flex; flex-direction: column; }
|
|
192
|
+
.content { flex: 1; max-width: 800px; margin: 0 auto; padding: 2rem; width: 100%; }
|
|
193
|
+
|
|
194
|
+
.nav {
|
|
195
|
+
display: flex; align-items: center; gap: 2rem;
|
|
196
|
+
padding: 1rem 2rem; background: #1a1a2e; color: white;
|
|
197
|
+
}
|
|
198
|
+
.nav-logo { color: white; text-decoration: none; font-weight: 700; font-size: 1.25rem; }
|
|
199
|
+
.nav-links { display: flex; gap: 1rem; }
|
|
200
|
+
.nav-links a { color: #a0a0c0; text-decoration: none; transition: color 0.2s; }
|
|
201
|
+
.nav-links a:hover { color: white; }
|
|
202
|
+
|
|
203
|
+
.footer { padding: 1rem 2rem; text-align: center; color: #666; font-size: 0.875rem; }
|
|
204
|
+
|
|
205
|
+
h1 { font-size: 2.5rem; margin-bottom: 1rem; }
|
|
206
|
+
p { margin-bottom: 1rem; }
|
|
207
|
+
|
|
208
|
+
.counter {
|
|
209
|
+
display: flex; align-items: center; gap: 1rem; margin-top: 1.5rem;
|
|
210
|
+
}
|
|
211
|
+
.counter button {
|
|
212
|
+
width: 40px; height: 40px; border-radius: 8px; border: 2px solid #1a1a2e;
|
|
213
|
+
background: white; font-size: 1.25rem; cursor: pointer; transition: all 0.15s;
|
|
214
|
+
}
|
|
215
|
+
.counter button:hover { background: #1a1a2e; color: white; }
|
|
216
|
+
.count { font-size: 2rem; font-weight: 700; min-width: 3rem; text-align: center; }
|
|
217
|
+
|
|
218
|
+
ul { margin-left: 1.5rem; margin-bottom: 1rem; }
|
|
219
|
+
li { margin-bottom: 0.25rem; }
|
|
220
|
+
|
|
221
|
+
.not-found { text-align: center; padding: 4rem 2rem; }
|
|
222
|
+
.not-found h1 { font-size: 6rem; color: #ddd; }
|
|
223
|
+
`);
|
|
224
|
+
|
|
225
|
+
console.log(` Done! Next steps:\n`);
|
|
226
|
+
console.log(` cd ${name}`);
|
|
227
|
+
console.log(` npm install`);
|
|
228
|
+
console.log(` npm run dev\n`);
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-what",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Scaffold a new What Framework project",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-what": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"index.js",
|
|
12
|
+
"templates"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"create",
|
|
16
|
+
"scaffold",
|
|
17
|
+
"template",
|
|
18
|
+
"what-framework"
|
|
19
|
+
],
|
|
20
|
+
"author": "",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/aspect/what-fw"
|
|
25
|
+
}
|
|
26
|
+
}
|