create-aziz-app 2.0.14 โ†’ 3.0.0

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 (60) hide show
  1. package/README.md +227 -0
  2. package/bin/create-aziz-app.js +9 -9
  3. package/package.json +10 -11
  4. package/template/README.md +862 -138
  5. package/template/_framework/boot.js +36 -0
  6. package/template/_framework/hooks.js +207 -0
  7. package/template/{modules โ†’ _framework}/next-response.js +5 -13
  8. package/template/_framework/router.js +279 -0
  9. package/template/_framework/runtime.js +86 -0
  10. package/template/api/createUser.js +1 -1
  11. package/template/api/hello.js +8 -17
  12. package/template/api/loginUser.js +1 -1
  13. package/template/api/users.js +38 -134
  14. package/template/app/about/page.js +45 -0
  15. package/template/app/layout.js +23 -0
  16. package/template/app/page.js +54 -0
  17. package/template/app/test/page.js +55 -0
  18. package/template/components/Footer.js +10 -0
  19. package/template/components/Navbar.js +30 -0
  20. package/template/index.html +24 -0
  21. package/template/package.json +5 -14
  22. package/template/scripts/dev-server.js +330 -302
  23. package/template/scripts/live-reload-client.js +0 -1
  24. package/template/.vscode/settings.json +0 -15
  25. package/template/api/getUser.js +0 -60
  26. package/template/api/getUserWithDB.js +0 -65
  27. package/template/app.config.js +0 -41
  28. package/template/app.html +0 -55
  29. package/template/components/Counter.jsx +0 -36
  30. package/template/components/Footer.jsx +0 -9
  31. package/template/components/Navbar.jsx +0 -17
  32. package/template/docs/API-GUIDE.md +0 -196
  33. package/template/docs/API-ROUTES.md +0 -538
  34. package/template/docs/AUTO-IMPORT.md +0 -99
  35. package/template/docs/AUTO-REGISTRATION.md +0 -248
  36. package/template/docs/CSS-FRAMEWORKS.md +0 -221
  37. package/template/docs/DEV-SERVER.md +0 -184
  38. package/template/docs/GETTING-STARTED.md +0 -205
  39. package/template/docs/HOW-IT-WORKS.md +0 -362
  40. package/template/docs/NEXTJS-APP-ROUTER.md +0 -536
  41. package/template/docs/NEXTJS-COMPARISON.md +0 -473
  42. package/template/docs/QUICK-START.md +0 -111
  43. package/template/docs/STYLING.md +0 -269
  44. package/template/docs/TROUBLESHOOTING.md +0 -282
  45. package/template/modules/README.md +0 -129
  46. package/template/modules/api.js +0 -44
  47. package/template/modules/auto-import.js +0 -130
  48. package/template/modules/router.js +0 -218
  49. package/template/modules/state.js +0 -248
  50. package/template/package-lock.json +0 -13
  51. package/template/pages/About.jsx +0 -48
  52. package/template/pages/ApiDemo.jsx +0 -209
  53. package/template/pages/Contact.jsx +0 -25
  54. package/template/pages/Example.jsx +0 -59
  55. package/template/pages/Home.jsx +0 -39
  56. package/template/pages/HooksDemo.jsx +0 -194
  57. package/template/pages/test.jsx +0 -72
  58. package/template/scripts/build.js +0 -81
  59. package/template/scripts/generate-imports.js +0 -88
  60. package/template/tailwind.config.js +0 -17
@@ -1,209 +0,0 @@
1
- /** @jsx h */
2
-
3
- // Auto-registered as "api-demo" route (or manually register for custom name)
4
- registerPage("api-demo", ApiDemoPage);
5
-
6
- function ApiDemoPage() {
7
- const [users, setUsers] = useState([]);
8
- const [loading, setLoading] = useState(false);
9
- const [message, setMessage] = useState('');
10
- const [newUserName, setNewUserName] = useState('');
11
- const [newUserEmail, setNewUserEmail] = useState('');
12
-
13
- // Fetch users from API
14
- const fetchUsers = async () => {
15
- setLoading(true);
16
- try {
17
- const response = await fetchApi('/api/users');
18
- const data = await response.json();
19
- setUsers(data);
20
- setMessage('Users loaded successfully!');
21
- } catch (error) {
22
- setMessage('Error loading users: ' + error.message);
23
- }
24
- setLoading(false);
25
- };
26
-
27
- // Test hello API
28
- const testHelloApi = async () => {
29
- try {
30
- const response = await fetchApi('/api/hello?name=Aziz');
31
- const data = await response.json();
32
- setMessage(data.message);
33
- } catch (error) {
34
- setMessage('Error: ' + error.message);
35
- }
36
- };
37
-
38
- // Add new user
39
- const addUser = async (e) => {
40
- e.preventDefault();
41
- if (!newUserName || !newUserEmail) {
42
- setMessage('Please fill in all fields');
43
- return;
44
- }
45
-
46
- setLoading(true);
47
- try {
48
- const response = await fetchApi('/api/users', {
49
- method: 'POST',
50
- body: JSON.stringify({
51
- name: newUserName,
52
- email: newUserEmail
53
- })
54
- });
55
- const data = await response.json();
56
- setMessage(`User added: ${data.name}`);
57
- setNewUserName('');
58
- setNewUserEmail('');
59
- // Refresh users list
60
- fetchUsers();
61
- } catch (error) {
62
- setMessage('Error adding user: ' + error.message);
63
- }
64
- setLoading(false);
65
- };
66
-
67
- // Delete user
68
- const deleteUser = async (userId) => {
69
- setLoading(true);
70
- try {
71
- const response = await fetchApi(`/api/users?id=${userId}`, {
72
- method: 'DELETE'
73
- });
74
- const data = await response.json();
75
- setMessage(data.message);
76
- // Refresh users list
77
- fetchUsers();
78
- } catch (error) {
79
- setMessage('Error deleting user: ' + error.message);
80
- }
81
- setLoading(false);
82
- };
83
-
84
- return (
85
- <div>
86
- <h1>API Routes Demo ๐Ÿš€</h1>
87
-
88
- <div class="card">
89
- <h2>Test API Endpoints</h2>
90
- <p>This demonstrates the Next.js-like API route system.</p>
91
-
92
- <div style={{ display: 'flex', gap: '12px', marginBottom: '16px' }}>
93
- <button class="btn btn-primary" onClick={testHelloApi}>
94
- Test /api/hello
95
- </button>
96
- <button class="btn btn-primary" onClick={fetchUsers}>
97
- Fetch Users
98
- </button>
99
- </div>
100
-
101
- {message && (
102
- <div style={{
103
- padding: '12px',
104
- background: '#e3f2fd',
105
- borderRadius: '8px',
106
- marginTop: '12px',
107
- color: '#1976d2'
108
- }}>
109
- {message}
110
- </div>
111
- )}
112
- </div>
113
-
114
- <div class="card">
115
- <h2>Add New User</h2>
116
- <form onSubmit={addUser}>
117
- <div>
118
- <label>Name:</label>
119
- <input
120
- type="text"
121
- value={newUserName}
122
- onInput={(e) => setNewUserName(e.target.value)}
123
- placeholder="Enter name"
124
- />
125
- </div>
126
-
127
- <div>
128
- <label>Email:</label>
129
- <input
130
- type="email"
131
- value={newUserEmail}
132
- onInput={(e) => setNewUserEmail(e.target.value)}
133
- placeholder="Enter email"
134
- />
135
- </div>
136
-
137
- <button type="submit" class="btn btn-primary" disabled={loading}>
138
- {loading ? 'Adding...' : 'Add User'}
139
- </button>
140
- </form>
141
- </div>
142
-
143
- <div class="card">
144
- <h2>Users List</h2>
145
- {loading && <p>Loading...</p>}
146
-
147
- {users.length === 0 && !loading && (
148
- <p>No users loaded. Click "Fetch Users" to load data.</p>
149
- )}
150
-
151
- {users.length > 0 && (
152
- <div>
153
- {users.map(user => (
154
- <div style={{
155
- padding: '12px',
156
- background: '#f5f5f5',
157
- borderRadius: '8px',
158
- marginBottom: '8px',
159
- display: 'flex',
160
- justifyContent: 'space-between',
161
- alignItems: 'center'
162
- }}>
163
- <div>
164
- <strong>{user.name}</strong>
165
- <br />
166
- <span style={{ fontSize: '14px', color: '#666' }}>
167
- {user.email}
168
- </span>
169
- </div>
170
- <button
171
- class="btn btn-danger"
172
- onClick={() => deleteUser(user.id)}
173
- disabled={loading}
174
- >
175
- Delete
176
- </button>
177
- </div>
178
- ))}
179
- </div>
180
- )}
181
- </div>
182
-
183
- <div class="card">
184
- <h2>How to Use API Routes</h2>
185
- <p>Create API routes in the <code>api/</code> folder:</p>
186
- <pre style={{
187
- background: '#282c34',
188
- color: '#61dafb',
189
- padding: '16px',
190
- borderRadius: '8px',
191
- overflow: 'auto'
192
- }}>
193
- {`// api/myroute.js
194
- registerApiRoute('myroute', async (req, res) => {
195
- if (req.method === 'GET') {
196
- return res.status(200).json({
197
- message: 'Hello!'
198
- });
199
- }
200
- });
201
-
202
- // Use in components
203
- const response = await fetchApi('/api/myroute');
204
- const data = await response.json();`}
205
- </pre>
206
- </div>
207
- </div>
208
- );
209
- }
@@ -1,25 +0,0 @@
1
- /** @jsx h */
2
-
3
- // Auto-registered as "contact" route
4
- function ContactPage() {
5
- return (
6
- <div>
7
- <h1>Contact ๐Ÿ“ฌ</h1>
8
-
9
- <div class="card">
10
- <h2>Get in touch</h2>
11
- <p>Fill out the form below and we'll get back to you.</p>
12
-
13
- <form onSubmit={(e) => {
14
- e.preventDefault();
15
- alert("Message sent! (wire this up to a backend)");
16
- }}>
17
- <input type="text" placeholder="Your name" required />
18
- <input type="email" placeholder="Your email" required />
19
- <textarea placeholder="Your message" required></textarea>
20
- <button type="submit" class="btn btn-primary">Send Message</button>
21
- </form>
22
- </div>
23
- </div>
24
- );
25
- }
@@ -1,59 +0,0 @@
1
- /** @jsx h */
2
-
3
- // That's it! No registerPage() needed.
4
- // This automatically becomes route "#/example"
5
- function ExamplePage() {
6
- const [message, setMessage] = useState('Hello from Example Page! ๐ŸŽ‰');
7
-
8
- return (
9
- <div>
10
- <h1>Example Page</h1>
11
-
12
- <div class="card">
13
- <h2>โœจ Auto-Registration Demo</h2>
14
- <p>
15
- This page was created without calling <code>registerPage()</code>.
16
- Just define a function ending with "Page" and it works!
17
- </p>
18
-
19
- <div style={{
20
- background: '#f0f0f0',
21
- padding: '16px',
22
- borderRadius: '8px',
23
- fontFamily: 'monospace',
24
- fontSize: '14px'
25
- }}>
26
- <strong>Function name:</strong> ExamplePage()<br/>
27
- <strong>Auto route:</strong> #/example<br/>
28
- <strong>URL:</strong> {window.location.href}
29
- </div>
30
- </div>
31
-
32
- <div class="card">
33
- <h2>State Management Works Too</h2>
34
- <p>{message}</p>
35
- <button
36
- class="btn btn-primary"
37
- onClick={() => setMessage('State updated! โœ…')}
38
- >
39
- Update Message
40
- </button>
41
- </div>
42
-
43
- <div class="card">
44
- <h2>Navigation</h2>
45
- <div style={{ display: 'flex', gap: '12px' }}>
46
- <button class="btn btn-primary" onClick={() => navigate("home")}>
47
- Home
48
- </button>
49
- <button class="btn btn-primary" onClick={() => navigate("about")}>
50
- About
51
- </button>
52
- <button class="btn btn-primary" onClick={() => navigate("test")}>
53
- Test
54
- </button>
55
- </div>
56
- </div>
57
- </div>
58
- );
59
- }
@@ -1,39 +0,0 @@
1
- /** @jsx h */
2
-
3
- // Auto-registered as "home" route
4
- function HomePage() {
5
- return (
6
- <div>
7
- <h1>Welcome Home ๐Ÿ‘‹</h1>
8
-
9
- <div class="card">
10
- <h2>Global State Counter</h2>
11
- <p>This uses the global state. Click the buttons to update it.</p>
12
-
13
- <div class="count-display">{state.count}</div>
14
-
15
- <div class="counter-actions">
16
- <button class="btn btn-danger" onClick={() => setState({ count: state.count - 1 })}>โˆ’</button>
17
- <button class="btn btn-primary" onClick={() => setState({ count: state.count + 1 })}>+</button>
18
- <button class="btn btn-grey" onClick={() => setState({ count: 0 })}>Reset</button>
19
- </div>
20
- </div>
21
-
22
- <div class="card">
23
- <h2>File-based Routing</h2>
24
- <p>
25
- Each file in <strong>pages/</strong> is a route โ€” just like Next.js.
26
- Add a new file, run the build script, and it's a new page.
27
- </p>
28
- <div style={{ display: 'flex', gap: '12px' }}>
29
- <button class="btn btn-primary" onClick={() => navigate("test")}>
30
- Go to Test Page โ†’
31
- </button>
32
- <button class="btn btn-primary" onClick={() => navigate("about")}>
33
- Go to About โ†’
34
- </button>
35
- </div>
36
- </div>
37
- </div>
38
- );
39
- }
@@ -1,194 +0,0 @@
1
- /** @jsx h */
2
-
3
- // Demo page showing all React-like hooks
4
- function HooksDemoPage() {
5
- // useState - Basic state
6
- const [count, setCount] = useState(0);
7
- const [name, setName] = useState('');
8
-
9
- // useEffect - Side effects
10
- useEffect(() => {
11
- console.log('Component mounted!');
12
- document.title = `Count: ${count}`;
13
-
14
- return () => {
15
- console.log('Cleanup!');
16
- };
17
- }, [count]);
18
-
19
- // useMemo - Memoized value
20
- const expensiveValue = useMemo(() => {
21
- console.log('Computing expensive value...');
22
- return count * 2;
23
- }, [count]);
24
-
25
- // useCallback - Memoized function
26
- const handleIncrement = useCallback(() => {
27
- setCount(c => c + 1);
28
- }, []);
29
-
30
- // useRef - Mutable ref
31
- const inputRef = useRef(null);
32
-
33
- const focusInput = () => {
34
- if (inputRef.current) {
35
- inputRef.current.focus();
36
- }
37
- };
38
-
39
- // useReducer - Complex state
40
- const [state, dispatch] = useReducer((state, action) => {
41
- switch (action.type) {
42
- case 'increment':
43
- return { ...state, value: state.value + 1 };
44
- case 'decrement':
45
- return { ...state, value: state.value - 1 };
46
- case 'reset':
47
- return { ...state, value: 0 };
48
- default:
49
- return state;
50
- }
51
- }, { value: 0 });
52
-
53
- // useLocalStorage - Custom hook
54
- const [savedName, setSavedName] = useLocalStorage('userName', '');
55
-
56
- // useFetch - Custom hook
57
- const { data, loading, error } = useFetch('/api/hello?name=Hooks');
58
-
59
- return (
60
- <div>
61
- <h1>React Hooks Demo ๐Ÿช</h1>
62
-
63
- <div class="card">
64
- <h2>useState</h2>
65
- <p>Basic state management</p>
66
- <div class="count-display">{count}</div>
67
- <div class="counter-actions">
68
- <button class="btn btn-primary" onClick={() => setCount(count + 1)}>
69
- Increment
70
- </button>
71
- <button class="btn btn-danger" onClick={() => setCount(count - 1)}>
72
- Decrement
73
- </button>
74
- <button class="btn btn-grey" onClick={() => setCount(0)}>
75
- Reset
76
- </button>
77
- </div>
78
- </div>
79
-
80
- <div class="card">
81
- <h2>useEffect</h2>
82
- <p>Check the browser console and page title!</p>
83
- <p>Current count: <strong>{count}</strong></p>
84
- <p style={{ color: '#666', fontSize: '14px' }}>
85
- useEffect runs after render and updates the document title
86
- </p>
87
- </div>
88
-
89
- <div class="card">
90
- <h2>useMemo</h2>
91
- <p>Memoized expensive computation</p>
92
- <p>Count ร— 2 = <strong>{expensiveValue}</strong></p>
93
- <p style={{ color: '#666', fontSize: '14px' }}>
94
- Check console - computation only runs when count changes
95
- </p>
96
- </div>
97
-
98
- <div class="card">
99
- <h2>useCallback</h2>
100
- <p>Memoized callback function</p>
101
- <button class="btn btn-primary" onClick={handleIncrement}>
102
- Increment (Memoized)
103
- </button>
104
- <p style={{ color: '#666', fontSize: '14px', marginTop: '8px' }}>
105
- Function reference stays the same between renders
106
- </p>
107
- </div>
108
-
109
- <div class="card">
110
- <h2>useRef</h2>
111
- <p>Mutable reference to DOM element</p>
112
- <input
113
- ref={inputRef}
114
- type="text"
115
- placeholder="Click button to focus me"
116
- value={name}
117
- onInput={(e) => setName(e.target.value)}
118
- />
119
- <button class="btn btn-primary" onClick={focusInput} style={{ marginTop: '8px' }}>
120
- Focus Input
121
- </button>
122
- </div>
123
-
124
- <div class="card">
125
- <h2>useReducer</h2>
126
- <p>Complex state management with actions</p>
127
- <div class="count-display">{state.value}</div>
128
- <div class="counter-actions">
129
- <button class="btn btn-primary" onClick={() => dispatch({ type: 'increment' })}>
130
- +
131
- </button>
132
- <button class="btn btn-danger" onClick={() => dispatch({ type: 'decrement' })}>
133
- โˆ’
134
- </button>
135
- <button class="btn btn-grey" onClick={() => dispatch({ type: 'reset' })}>
136
- Reset
137
- </button>
138
- </div>
139
- </div>
140
-
141
- <div class="card">
142
- <h2>useLocalStorage</h2>
143
- <p>Persistent state in localStorage</p>
144
- <input
145
- type="text"
146
- placeholder="Enter your name"
147
- value={savedName}
148
- onInput={(e) => setSavedName(e.target.value)}
149
- />
150
- <p style={{ marginTop: '8px' }}>
151
- Saved name: <strong>{savedName || 'Not set'}</strong>
152
- </p>
153
- <p style={{ color: '#666', fontSize: '14px' }}>
154
- Refresh the page - your name persists!
155
- </p>
156
- </div>
157
-
158
- <div class="card">
159
- <h2>useFetch</h2>
160
- <p>Data fetching with loading and error states</p>
161
- {loading && <p>Loading...</p>}
162
- {error && <p style={{ color: 'red' }}>Error: {error}</p>}
163
- {data && (
164
- <div style={{
165
- background: '#f0f0f0',
166
- padding: '12px',
167
- borderRadius: '8px',
168
- fontFamily: 'monospace',
169
- fontSize: '14px'
170
- }}>
171
- <pre>{JSON.stringify(data, null, 2)}</pre>
172
- </div>
173
- )}
174
- </div>
175
-
176
- <div class="card">
177
- <h2>All Hooks Available</h2>
178
- <ul style={{ lineHeight: '1.8', marginLeft: '20px' }}>
179
- <li><code>useState</code> - State management</li>
180
- <li><code>useEffect</code> - Side effects</li>
181
- <li><code>useMemo</code> - Memoized values</li>
182
- <li><code>useCallback</code> - Memoized functions</li>
183
- <li><code>useRef</code> - Mutable refs</li>
184
- <li><code>useReducer</code> - Complex state</li>
185
- <li><code>useLocalStorage</code> - Persistent state</li>
186
- <li><code>useFetch</code> - Data fetching</li>
187
- </ul>
188
- <p style={{ marginTop: '12px', color: '#666' }}>
189
- Just like React/Next.js! ๐ŸŽ‰
190
- </p>
191
- </div>
192
- </div>
193
- );
194
- }
@@ -1,72 +0,0 @@
1
- /** @jsx h */
2
-
3
- // Auto-registered as "test" route
4
- function TestPage() {
5
- const [count, setCount] = useState(0);
6
- const [name, setName] = useState('');
7
- const [email, setEmail] = useState('');
8
-
9
- const handleSubmit = (e) => {
10
- e.preventDefault();
11
- alert(`Form submitted!\nName: ${name}\nEmail: ${email}\nCount: ${count}`);
12
- };
13
-
14
- return (
15
- <div>
16
- <h1>Test Page ๐Ÿงช</h1>
17
-
18
- <div class="card">
19
- <h2>Counter Example</h2>
20
- <p>This demonstrates the state management system.</p>
21
-
22
- <div class="count-display">{count}</div>
23
- <div class="counter-actions">
24
- <button class="btn btn-primary" onClick={() => setCount(count + 1)}>
25
- Increment
26
- </button>
27
- <button class="btn btn-danger" onClick={() => setCount(0)}>
28
- Reset
29
- </button>
30
- </div>
31
- </div>
32
-
33
- <div class="card">
34
- <h2>Form Example</h2>
35
- <p>Try the form with state management.</p>
36
-
37
- <form onSubmit={handleSubmit}>
38
- <div>
39
- <label>Name:</label>
40
- <input
41
- type="text"
42
- value={name}
43
- onInput={(e) => setName(e.target.value)}
44
- placeholder="Enter your name"
45
- />
46
- </div>
47
-
48
- <div>
49
- <label>Email:</label>
50
- <input
51
- type="email"
52
- value={email}
53
- onInput={(e) => setEmail(e.target.value)}
54
- placeholder="Enter your email"
55
- />
56
- </div>
57
-
58
- <button type="submit" class="btn btn-primary">
59
- Submit Form
60
- </button>
61
- </form>
62
- </div>
63
-
64
- <div class="card">
65
- <h2>State Information</h2>
66
- <p>Current count: <strong>{count}</strong></p>
67
- <p>Current name: <strong>{name || 'Not set'}</strong></p>
68
- <p>Current email: <strong>{email || 'Not set'}</strong></p>
69
- </div>
70
- </div>
71
- );
72
- }
@@ -1,81 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- console.log('๐Ÿ” Scanning for pages, components, and API routes...\n');
7
-
8
- // Scan a directory for files
9
- function scanDirectory(dir, extensions = []) {
10
- const files = [];
11
-
12
- if (!fs.existsSync(dir)) {
13
- return files;
14
- }
15
-
16
- const items = fs.readdirSync(dir);
17
-
18
- for (const item of items) {
19
- const fullPath = path.join(dir, item);
20
- const stat = fs.statSync(fullPath);
21
-
22
- if (stat.isFile()) {
23
- const ext = path.extname(item);
24
- if (extensions.length === 0 || extensions.includes(ext)) {
25
- files.push(path.relative('.', fullPath).replace(/\\/g, '/'));
26
- }
27
- }
28
- }
29
-
30
- return files;
31
- }
32
-
33
- // Scan for files
34
- const apiRoutes = scanDirectory('api', ['.js']);
35
- const components = scanDirectory('components', ['.jsx', '.js']);
36
- const pages = scanDirectory('pages', ['.jsx', '.js']);
37
-
38
- console.log(`๐Ÿ“ก Found ${apiRoutes.length} API routes`);
39
- console.log(`๐Ÿงฉ Found ${components.length} components`);
40
- console.log(`๐Ÿ“„ Found ${pages.length} pages\n`);
41
-
42
- // Generate app.config.js
43
- const configContent = `// ============================================================
44
- // APP CONFIGURATION (AUTO-GENERATED)
45
- // This file is automatically generated by build.js
46
- // Run: node build.js to regenerate
47
- // ============================================================
48
-
49
- window.APP_CONFIG = {
50
- apiRoutes: ${JSON.stringify(apiRoutes, null, 8).replace(/\n/g, '\n ')},
51
-
52
- components: ${JSON.stringify(components, null, 8).replace(/\n/g, '\n ')},
53
-
54
- pages: ${JSON.stringify(pages, null, 8).replace(/\n/g, '\n ')}
55
- };
56
- `;
57
-
58
- fs.writeFileSync('app.config.js', configContent);
59
- console.log('โœ… Generated app.config.js\n');
60
-
61
- // Generate script tags for app.html
62
- const scriptTags = [];
63
-
64
- // Add API routes
65
- apiRoutes.forEach(route => {
66
- scriptTags.push(` <script type="text/babel" src="${route}"></script>`);
67
- });
68
-
69
- // Add components
70
- components.forEach(component => {
71
- scriptTags.push(` <script type="text/babel" src="${component}"></script>`);
72
- });
73
-
74
- // Add pages
75
- pages.forEach(page => {
76
- scriptTags.push(` <script type="text/babel" src="${page}"></script>`);
77
- });
78
-
79
- console.log('๐Ÿ“‹ Copy these script tags to app.html:\n');
80
- console.log(scriptTags.join('\n'));
81
- console.log('\nโœจ Done! Refresh your browser to see changes.');