react-client 1.0.9 β 1.0.10
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/README.md +0 -22
- package/dist/cli/commands/dev.js +21 -9
- package/dist/cli/index.js +1 -27
- package/package.json +2 -4
- package/templates/react/index.html +13 -1
- package/templates/react/public/favicon.ico +0 -0
- package/templates/react/src/App.jsx +1 -1
- package/templates/react/src/main.jsx +6 -1
- package/templates/react-tailwind/index.html +13 -1
- package/templates/react-tailwind/public/favicon.ico +0 -0
- package/templates/react-tailwind/src/App.jsx +3 -1
- package/templates/react-tailwind/src/index.css +1 -0
- package/templates/react-tailwind/src/main.jsx +9 -1
- package/templates/react-tailwind-ts/index.html +13 -1
- package/templates/react-tailwind-ts/public/favicon.ico +0 -0
- package/templates/react-tailwind-ts/src/App.tsx +3 -1
- package/templates/react-tailwind-ts/src/main.tsx +1 -0
- package/templates/react-ts/index.html +13 -1
- package/templates/react-ts/public/favicon.ico +0 -0
- package/templates/react-ts/src/main.tsx +6 -1
- package/templates/{react-ssr-ts β react-ts}/tsconfig.json +1 -2
- package/dist/cli/commands/build.ssr.js +0 -46
- package/dist/cli/commands/generate.js +0 -42
- package/templates/react-ssr/index.html +0 -1
- package/templates/react-ssr/package.json +0 -14
- package/templates/react-ssr/src/entry-client.jsx +0 -1
- package/templates/react-ssr/src/entry-server.jsx +0 -1
- package/templates/react-ssr/src/pages/index.jsx +0 -1
- package/templates/react-ssr-ts/index.html +0 -1
- package/templates/react-ssr-ts/package.json +0 -21
- package/templates/react-ssr-ts/src/entry-client.js +0 -5
- package/templates/react-ssr-ts/src/entry-client.tsx +0 -6
- package/templates/react-ssr-ts/src/entry-server.js +0 -4
- package/templates/react-ssr-ts/src/entry-server.tsx +0 -5
- package/templates/react-ssr-ts/src/pages/index.js +0 -2
- package/templates/react-ssr-ts/src/pages/index.tsx +0 -3
- package/templates/react-tailwind-ts/src/App.js +0 -2
- package/templates/react-tailwind-ts/src/main.js +0 -7
package/README.md
CHANGED
|
@@ -76,8 +76,6 @@ export default defineConfig({
|
|
|
76
76
|
|-----------|-------------|
|
|
77
77
|
| `react` | JavaScript SPA |
|
|
78
78
|
| `react-ts` | TypeScript SPA |
|
|
79
|
-
| `react-ssr` | JavaScript SSR |
|
|
80
|
-
| `react-ssr-ts` | TypeScript SSR |
|
|
81
79
|
| `react-tailwind` | JS + Tailwind |
|
|
82
80
|
| `react-tailwind-ts` | TS + Tailwind |
|
|
83
81
|
|
|
@@ -94,8 +92,6 @@ Each template is pre-configured for esbuild, HMR, and fast bootstrapping.
|
|
|
94
92
|
- π¬ **Auto Port Detection** β Prompts when default port 5173 is occupied
|
|
95
93
|
- π§ **Smart Config Loader** β Detects project root, compiles `.ts` configs dynamically
|
|
96
94
|
- π¨ **PrismJS Highlighting** β For pretty overlay code frames
|
|
97
|
-
- π§± **SSR Runtime Support** β For server-side templates (`react-ssr*`)
|
|
98
|
-
- π§© **Generators** β Create components, routes, and tests instantly
|
|
99
95
|
- π **Plugin Hook System** β Extendable with `configResolved`, `transform`, `buildEnd`
|
|
100
96
|
|
|
101
97
|
---
|
|
@@ -200,21 +196,3 @@ Found an issue or have a feature request?
|
|
|
200
196
|
## πͺͺ License
|
|
201
197
|
|
|
202
198
|
**MIT Licensed** Β© [Venkatesh Sundaram](https://github.com/venkateshsundaram)
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## πΊοΈ Architecture Overview (Bonus)
|
|
207
|
-
|
|
208
|
-
```text
|
|
209
|
-
βββββββββββββββββββββββββββββ
|
|
210
|
-
β react-client (CLI) β
|
|
211
|
-
β βββ esbuild (watch/bundle)
|
|
212
|
-
β βββ connect (dev server)
|
|
213
|
-
β βββ websocket (HMR)
|
|
214
|
-
β βββ prismjs overlay
|
|
215
|
-
β βββ chokidar (file watch)
|
|
216
|
-
βββββββββββββββββββββββββββββ
|
|
217
|
-
β
|
|
218
|
-
βΌ
|
|
219
|
-
Browser β Live HMR + Overlay
|
|
220
|
-
```
|
package/dist/cli/commands/dev.js
CHANGED
|
@@ -80,8 +80,13 @@ async function dev() {
|
|
|
80
80
|
outdir: outDir,
|
|
81
81
|
define: { 'process.env.NODE_ENV': '"development"' },
|
|
82
82
|
loader: { '.ts': 'ts', '.tsx': 'tsx', '.js': 'jsx', '.jsx': 'jsx' },
|
|
83
|
+
entryNames: '[name]', // β
output main.js (not src/main.js)
|
|
84
|
+
assetNames: 'assets/[name]',
|
|
83
85
|
});
|
|
84
86
|
await ctx.watch();
|
|
87
|
+
console.log(chalk_1.default.gray('π¦ Watching and building dev bundle...'));
|
|
88
|
+
console.log(chalk_1.default.gray(' Output dir:'), chalk_1.default.blue(outDir));
|
|
89
|
+
console.log(chalk_1.default.gray(' Entry file:'), chalk_1.default.yellow(entry));
|
|
85
90
|
// π connect server
|
|
86
91
|
const app = (0, connect_1.default)();
|
|
87
92
|
// π‘ Security headers
|
|
@@ -90,19 +95,20 @@ async function dev() {
|
|
|
90
95
|
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
|
|
91
96
|
next();
|
|
92
97
|
});
|
|
93
|
-
// 1οΈβ£ Serve react-refresh runtime with
|
|
98
|
+
// 1οΈβ£ Serve react-refresh runtime with safe browser shim
|
|
94
99
|
app.use('/@react-refresh', async (_req, res) => {
|
|
95
100
|
const runtime = await fs_extra_1.default.readFile(reactRefreshRuntime, 'utf8');
|
|
96
101
|
const shim = `
|
|
97
102
|
// React Refresh browser shims
|
|
98
103
|
window.process = window.process || { env: { NODE_ENV: 'development' } };
|
|
99
104
|
window.module = { exports: {} };
|
|
100
|
-
window.global = window;
|
|
105
|
+
window.global = window;
|
|
106
|
+
window.require = () => window.module.exports;
|
|
101
107
|
`;
|
|
102
108
|
res.setHeader('Content-Type', 'application/javascript');
|
|
103
109
|
res.end(shim + '\n' + runtime);
|
|
104
110
|
});
|
|
105
|
-
// 2οΈβ£ Serve PrismJS
|
|
111
|
+
// 2οΈβ£ Serve PrismJS for code highlighting (overlay)
|
|
106
112
|
app.use('/@prismjs', async (_req, res) => {
|
|
107
113
|
const prismPath = require.resolve('prismjs/prism.js');
|
|
108
114
|
const css = await fs_extra_1.default.readFile(require.resolve('prismjs/themes/prism-tomorrow.css'), 'utf8');
|
|
@@ -165,7 +171,7 @@ async function dev() {
|
|
|
165
171
|
res.end(JSON.stringify({ error: msg }));
|
|
166
172
|
}
|
|
167
173
|
});
|
|
168
|
-
// 4οΈβ£ Serve
|
|
174
|
+
// 4οΈβ£ Serve index.html with injected refresh + HMR
|
|
169
175
|
app.use(async (req, res, next) => {
|
|
170
176
|
if (req.url === '/' || req.url === '/index.html') {
|
|
171
177
|
if (!fs_extra_1.default.existsSync(indexHtml)) {
|
|
@@ -174,10 +180,7 @@ async function dev() {
|
|
|
174
180
|
return;
|
|
175
181
|
}
|
|
176
182
|
let html = await fs_extra_1.default.readFile(indexHtml, 'utf8');
|
|
177
|
-
// Ensure main entry reference
|
|
178
|
-
html = html.replace(/<script[^>]*src="\/bundle\.js"[^>]*><\/script>/, '');
|
|
179
183
|
html = html.replace('</body>', `
|
|
180
|
-
<script type="module" src="/main.js"></script>
|
|
181
184
|
<script type="module">
|
|
182
185
|
import "/@react-refresh";
|
|
183
186
|
import "/@prismjs";
|
|
@@ -204,8 +207,17 @@ async function dev() {
|
|
|
204
207
|
res.setHeader('Content-Type', 'text/html');
|
|
205
208
|
res.end(html);
|
|
206
209
|
}
|
|
207
|
-
else
|
|
208
|
-
|
|
210
|
+
else {
|
|
211
|
+
// β
Serve compiled output files
|
|
212
|
+
const filePath = path_1.default.join(outDir, req.url || '');
|
|
213
|
+
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
214
|
+
const content = await fs_extra_1.default.readFile(filePath);
|
|
215
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
216
|
+
res.end(content);
|
|
217
|
+
}
|
|
218
|
+
else
|
|
219
|
+
next();
|
|
220
|
+
}
|
|
209
221
|
});
|
|
210
222
|
const server = http_1.default.createServer(app);
|
|
211
223
|
const wss = new ws_1.WebSocketServer({ server });
|
package/dist/cli/index.js
CHANGED
|
@@ -9,10 +9,8 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const init_1 = __importDefault(require("./commands/init"));
|
|
12
|
-
const generate_1 = __importDefault(require("./commands/generate"));
|
|
13
12
|
const dev_1 = __importDefault(require("./commands/dev"));
|
|
14
13
|
const build_1 = __importDefault(require("./commands/build"));
|
|
15
|
-
const build_ssr_1 = __importDefault(require("./commands/build.ssr"));
|
|
16
14
|
const preview_1 = __importDefault(require("./commands/preview"));
|
|
17
15
|
// Load package.json version dynamically
|
|
18
16
|
const pkgPath = path_1.default.resolve(__dirname, '../../package.json');
|
|
@@ -23,7 +21,7 @@ const pkg = fs_extra_1.default.existsSync(pkgPath)
|
|
|
23
21
|
function showBanner(cmd) {
|
|
24
22
|
const title = chalk_1.default.bold.cyan('β‘ React Client');
|
|
25
23
|
const version = chalk_1.default.gray(`v${pkg.version}`);
|
|
26
|
-
const tagline = chalk_1.default.dim('Fast esbuild-based React CLI with HMR
|
|
24
|
+
const tagline = chalk_1.default.dim('Fast esbuild-based React CLI with HMR & Overlay');
|
|
27
25
|
const line = chalk_1.default.gray('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ');
|
|
28
26
|
console.log(`\n${title} ${version}`);
|
|
29
27
|
console.log(tagline);
|
|
@@ -32,18 +30,12 @@ function showBanner(cmd) {
|
|
|
32
30
|
case 'init':
|
|
33
31
|
console.log(chalk_1.default.cyan('π¦ Initializing new React project...\n'));
|
|
34
32
|
break;
|
|
35
|
-
case 'generate':
|
|
36
|
-
console.log(chalk_1.default.white('β¨ Generating boilerplate files...\n'));
|
|
37
|
-
break;
|
|
38
33
|
case 'dev':
|
|
39
34
|
console.log(chalk_1.default.green('π Starting development server...\n'));
|
|
40
35
|
break;
|
|
41
36
|
case 'build':
|
|
42
37
|
console.log(chalk_1.default.yellow('ποΈ Building for production...\n'));
|
|
43
38
|
break;
|
|
44
|
-
case 'build:ssr':
|
|
45
|
-
console.log(chalk_1.default.magenta('π§± Building for server-side rendering (SSR)...\n'));
|
|
46
|
-
break;
|
|
47
39
|
case 'preview':
|
|
48
40
|
console.log(chalk_1.default.blue('π Starting production preview server...\n'));
|
|
49
41
|
break;
|
|
@@ -69,17 +61,6 @@ program
|
|
|
69
61
|
showBanner('init');
|
|
70
62
|
(0, init_1.default)(name, opts);
|
|
71
63
|
});
|
|
72
|
-
program
|
|
73
|
-
.command('generate <kind> <name>')
|
|
74
|
-
.alias('g')
|
|
75
|
-
.option('-p, --path <path>', 'output path')
|
|
76
|
-
.option('--no-ts', 'generate JS instead of TS')
|
|
77
|
-
.option('-f, --force', 'overwrite if exists')
|
|
78
|
-
.description('generate components, pages, or stores')
|
|
79
|
-
.action((kind, name, opts) => {
|
|
80
|
-
showBanner('generate');
|
|
81
|
-
(0, generate_1.default)(kind, name, opts);
|
|
82
|
-
});
|
|
83
64
|
program
|
|
84
65
|
.command('dev')
|
|
85
66
|
.description('start dev server (with React Fast Refresh)')
|
|
@@ -94,13 +75,6 @@ program
|
|
|
94
75
|
showBanner('build');
|
|
95
76
|
(0, build_1.default)();
|
|
96
77
|
});
|
|
97
|
-
program
|
|
98
|
-
.command('build:ssr')
|
|
99
|
-
.description('build for server-side rendering (SSR)')
|
|
100
|
-
.action(() => {
|
|
101
|
-
showBanner('build:ssr');
|
|
102
|
-
(0, build_ssr_1.default)();
|
|
103
|
-
});
|
|
104
78
|
program
|
|
105
79
|
.command('preview')
|
|
106
80
|
.description('preview production build')
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-client",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "react-client is a lightweight CLI and runtime for building React apps with fast iteration.
|
|
3
|
+
"version": "1.0.10",
|
|
4
|
+
"description": "react-client is a lightweight CLI and runtime for building React apps with fast iteration.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Venkatesh Sundaram",
|
|
7
7
|
"repository": {
|
|
@@ -51,7 +51,6 @@
|
|
|
51
51
|
"react-cli",
|
|
52
52
|
"framework",
|
|
53
53
|
"hmr",
|
|
54
|
-
"ssr",
|
|
55
54
|
"esbuild",
|
|
56
55
|
"tooling",
|
|
57
56
|
"vite-alternative",
|
|
@@ -65,7 +64,6 @@
|
|
|
65
64
|
"compile": "tsc -p tsconfig.build.json",
|
|
66
65
|
"build": "npm run clean && npm run compile",
|
|
67
66
|
"build:cli": "node dist/cli/index.js build",
|
|
68
|
-
"build:ssr": "node dist/cli/index.js build:ssr",
|
|
69
67
|
"dev": "node dist/cli/index.js dev",
|
|
70
68
|
"prepare": "npm run compile",
|
|
71
69
|
"lint": "eslint . --ext .ts --max-warnings 0",
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>React Client App</title>
|
|
7
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id='root'></div>
|
|
11
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default ()=> <div>Hello React</div>;
|
|
1
|
+
export default () => <div>Hello React</div>;
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import App from './App';
|
|
4
|
+
|
|
5
|
+
const root = createRoot(document.getElementById('root'));
|
|
6
|
+
root.render(<App />);
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>React Client App</title>
|
|
7
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id='root'></div>
|
|
11
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@tailwind base;@tailwind components;@tailwind utilities;
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
import '/@react-refresh-shim';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { createRoot } from 'react-dom/client';
|
|
5
|
+
import App from './App';
|
|
6
|
+
import './index.css';
|
|
7
|
+
|
|
8
|
+
const root = createRoot(document.getElementById('root'));
|
|
9
|
+
root.render(<App/>);
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>React Client App</title>
|
|
7
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id='root'></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
Binary file
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
export default function App(){
|
|
2
|
+
export default function App() {
|
|
3
|
+
return <div className='p-8'><h1 className='text-2xl font-bold'>Tailwind TS</h1><p>Welcome to react-tailwind-ts template.</p></div>;
|
|
4
|
+
}
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>React Client App</title>
|
|
7
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id='root'></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
Binary file
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import App from './App';
|
|
4
|
+
|
|
5
|
+
const root = createRoot(document.getElementById('root')!);
|
|
6
|
+
root.render(<App/>);
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.default = buildSsr;
|
|
7
|
-
const esbuild_1 = __importDefault(require("esbuild"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
-
const loadConfig_1 = require("../../utils/loadConfig");
|
|
12
|
-
async function buildSsr() {
|
|
13
|
-
const root = process.cwd();
|
|
14
|
-
const config = await (0, loadConfig_1.loadReactClientConfig)(root);
|
|
15
|
-
const appRoot = path_1.default.resolve(root, config.root || '.');
|
|
16
|
-
const outDir = path_1.default.join(appRoot, config.build?.outDir || '.react-client/ssr');
|
|
17
|
-
console.log(chalk_1.default.cyan(`\nπ§± Building SSR bundle...`));
|
|
18
|
-
console.log(chalk_1.default.gray(`Root: ${appRoot}`));
|
|
19
|
-
console.log(chalk_1.default.gray(`Output: ${outDir}\n`));
|
|
20
|
-
const entry = path_1.default.join(appRoot, 'src', 'server.tsx');
|
|
21
|
-
if (!fs_extra_1.default.existsSync(entry)) {
|
|
22
|
-
console.error(chalk_1.default.red('β SSR entry not found: src/server.tsx'));
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
await fs_extra_1.default.ensureDir(outDir);
|
|
26
|
-
try {
|
|
27
|
-
await esbuild_1.default.build({
|
|
28
|
-
entryPoints: [entry],
|
|
29
|
-
bundle: true,
|
|
30
|
-
platform: 'node',
|
|
31
|
-
format: 'esm',
|
|
32
|
-
target: 'node18',
|
|
33
|
-
external: ['react', 'react-dom'],
|
|
34
|
-
outdir: outDir,
|
|
35
|
-
define: { 'process.env.NODE_ENV': '"production"' },
|
|
36
|
-
loader: { '.ts': 'ts', '.tsx': 'tsx' },
|
|
37
|
-
});
|
|
38
|
-
console.log(chalk_1.default.green(`β
SSR build completed successfully!`));
|
|
39
|
-
console.log(chalk_1.default.gray(`Output directory: ${outDir}`));
|
|
40
|
-
}
|
|
41
|
-
catch (err) {
|
|
42
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
43
|
-
console.error('β SSR build failed:', msg);
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.default = generate;
|
|
7
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const string_1 = require("../../utils/string");
|
|
10
|
-
async function generate(kind, name, opts = {}) {
|
|
11
|
-
const root = process.cwd();
|
|
12
|
-
const useTS = opts.ts !== false && opts['no-ts'] !== true;
|
|
13
|
-
if (kind === 'component') {
|
|
14
|
-
const pascal = (0, string_1.pascalCase)(name);
|
|
15
|
-
const dir = path_1.default.join(root, opts.path || 'src/components');
|
|
16
|
-
await fs_extra_1.default.ensureDir(dir);
|
|
17
|
-
const ext = useTS ? 'tsx' : 'jsx';
|
|
18
|
-
const compPath = path_1.default.join(dir, `${pascal}.${ext}`);
|
|
19
|
-
const css = path_1.default.join(dir, `${pascal}.module.css`);
|
|
20
|
-
await fs_extra_1.default.writeFile(compPath, `import React from 'react';\nimport styles from './${pascal}.module.css';\nexport default function ${pascal}(){ return <div className={styles.root}>${pascal}</div>; }\n`);
|
|
21
|
-
await fs_extra_1.default.writeFile(css, `.root{display:block}`);
|
|
22
|
-
console.log('Created component', compPath);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
if (kind === 'route') {
|
|
26
|
-
const parts = name.replace(/^\//, '').split('/').filter(Boolean);
|
|
27
|
-
const pages = path_1.default.join(root, 'src', 'pages', ...parts.slice(0, -1));
|
|
28
|
-
await fs_extra_1.default.ensureDir(pages);
|
|
29
|
-
const last = parts[parts.length - 1] || 'index';
|
|
30
|
-
const file = path_1.default.join(pages, last + '.' + (useTS ? 'tsx' : 'jsx'));
|
|
31
|
-
if (await fs_extra_1.default.pathExists(file)) {
|
|
32
|
-
console.error('Route exists');
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
const compName = (0, string_1.pascalCase)(parts.join('-') || 'IndexPage');
|
|
36
|
-
const content = `import React from 'react';\nexport default function ${compName}(){ return (<div style={{padding:20}}><h1>${compName}</h1></div>); }\n`;
|
|
37
|
-
await fs_extra_1.default.writeFile(file, content, 'utf8');
|
|
38
|
-
console.log('Created route', file);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
console.log('Unknown generator', kind);
|
|
42
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<!doctype html><html><head><meta charset='utf-8'></head><body><div id='root'></div><script type='module' src='/main.js'></script></body></html>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "template-react-ssr",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"private": true,
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "react-client dev",
|
|
7
|
-
"build": "react-client build:ssr",
|
|
8
|
-
"preview": "react-client preview"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"react": "^18.2.0",
|
|
12
|
-
"react-dom": "^18.2.0"
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import React from 'react';import { hydrateRoot } from 'react-dom/client';import Home from './pages/index';hydrateRoot(document.getElementById('root'), React.createElement(Home));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import React from 'react';import { renderToString } from 'react-dom/server';import Home from './pages/index';exports.render = function(url){ const Page = Home; return Promise.resolve(renderToString(React.createElement(Page))); };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import React from 'react';export default function Home(){ return <div>Home SSR</div>; }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<!doctype html><html><head><meta charset='utf-8' /></head><body><div id='root'></div><script type='module' src='/main.js'></script></body></html>
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "my-react-ssr-ts-app",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"private": true,
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "react-client dev",
|
|
7
|
-
"build": "react-client build:ssr",
|
|
8
|
-
"preview": "react-client preview"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"react": "^18.2.0",
|
|
12
|
-
"react-dom": "^18.2.0"
|
|
13
|
-
},
|
|
14
|
-
"devDependencies": {
|
|
15
|
-
"@types/react": "^18.0.0",
|
|
16
|
-
"@types/react-dom": "^18.0.0",
|
|
17
|
-
"esbuild": "^0.25.12",
|
|
18
|
-
"react-refresh": "^0.14.0",
|
|
19
|
-
"typescript": "^5.0.0"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
export default function App() { return _jsxs("div", { className: 'p-8', children: [_jsx("h1", { className: 'text-2xl font-bold', children: "Tailwind TS" }), _jsx("p", { children: "Welcome to react-tailwind-ts template." })] }); }
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import '/@react-refresh-shim';
|
|
3
|
-
import { createRoot } from 'react-dom/client';
|
|
4
|
-
import App from './App';
|
|
5
|
-
import './index.css';
|
|
6
|
-
const root = createRoot(document.getElementById('root'));
|
|
7
|
-
root.render(_jsx(App, {}));
|