react-client 1.0.10 → 1.0.11
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/dist/cli/commands/dev.js +61 -65
- package/package.json +1 -2
package/dist/cli/commands/dev.js
CHANGED
|
@@ -13,7 +13,6 @@ const detect_port_1 = __importDefault(require("detect-port"));
|
|
|
13
13
|
const prompts_1 = __importDefault(require("prompts"));
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
15
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
16
|
-
const trace_mapping_1 = require("@jridgewell/trace-mapping");
|
|
17
16
|
const loadConfig_1 = require("../../utils/loadConfig");
|
|
18
17
|
const open_1 = __importDefault(require("open"));
|
|
19
18
|
const child_process_1 = require("child_process");
|
|
@@ -25,12 +24,14 @@ async function dev() {
|
|
|
25
24
|
const appRoot = path_1.default.resolve(root, userConfig.root || '.');
|
|
26
25
|
const defaultPort = userConfig.server?.port || 5173;
|
|
27
26
|
const outDir = path_1.default.join(appRoot, userConfig.build?.outDir || '.react-client/dev');
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
// ✅ Dynamically detect entry (main.tsx or main.jsx)
|
|
28
|
+
const possibleEntries = ['src/main.tsx', 'src/main.jsx'];
|
|
29
|
+
const entry = possibleEntries.map((p) => path_1.default.join(appRoot, p)).find((p) => fs_extra_1.default.existsSync(p));
|
|
30
|
+
if (!entry) {
|
|
31
|
+
console.error(chalk_1.default.red('❌ No entry found: src/main.tsx or src/main.jsx'));
|
|
32
32
|
process.exit(1);
|
|
33
33
|
}
|
|
34
|
+
const indexHtml = path_1.default.join(appRoot, 'index.html');
|
|
34
35
|
await fs_extra_1.default.ensureDir(outDir);
|
|
35
36
|
// 🧠 Detect open port
|
|
36
37
|
const availablePort = await (0, detect_port_1.default)(defaultPort);
|
|
@@ -80,7 +81,7 @@ async function dev() {
|
|
|
80
81
|
outdir: outDir,
|
|
81
82
|
define: { 'process.env.NODE_ENV': '"development"' },
|
|
82
83
|
loader: { '.ts': 'ts', '.tsx': 'tsx', '.js': 'jsx', '.jsx': 'jsx' },
|
|
83
|
-
entryNames: '[name]',
|
|
84
|
+
entryNames: '[name]',
|
|
84
85
|
assetNames: 'assets/[name]',
|
|
85
86
|
});
|
|
86
87
|
await ctx.watch();
|
|
@@ -108,67 +109,63 @@ async function dev() {
|
|
|
108
109
|
res.setHeader('Content-Type', 'application/javascript');
|
|
109
110
|
res.end(shim + '\n' + runtime);
|
|
110
111
|
});
|
|
111
|
-
// 2️⃣
|
|
112
|
-
app.use('/@
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const url = new URL(req.url ?? '', `http://localhost:${port}`);
|
|
129
|
-
const file = url.searchParams.get('file');
|
|
130
|
-
const line = Number(url.searchParams.get('line'));
|
|
131
|
-
const column = Number(url.searchParams.get('column'));
|
|
132
|
-
if (!file) {
|
|
133
|
-
res.writeHead(400);
|
|
134
|
-
res.end('Missing ?file parameter');
|
|
135
|
-
return;
|
|
112
|
+
// 2️⃣ Minimal bare import resolver (/@modules/)
|
|
113
|
+
app.use('/@modules/', async (req, res, next) => {
|
|
114
|
+
const id = req.url?.replace(/^\/@modules\//, '');
|
|
115
|
+
if (!id)
|
|
116
|
+
return next();
|
|
117
|
+
try {
|
|
118
|
+
const entry = require.resolve(id, { paths: [appRoot] });
|
|
119
|
+
const out = await esbuild_1.default.build({
|
|
120
|
+
entryPoints: [entry],
|
|
121
|
+
bundle: true,
|
|
122
|
+
write: false,
|
|
123
|
+
platform: 'browser',
|
|
124
|
+
format: 'esm',
|
|
125
|
+
target: 'es2020',
|
|
126
|
+
});
|
|
127
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
128
|
+
res.end(out.outputFiles[0].text);
|
|
136
129
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
res.writeHead(
|
|
140
|
-
res.end(
|
|
141
|
-
return;
|
|
130
|
+
catch (err) {
|
|
131
|
+
console.error('Failed to resolve module', id, err);
|
|
132
|
+
res.writeHead(500);
|
|
133
|
+
res.end(`// Could not resolve module ${id}`);
|
|
142
134
|
}
|
|
135
|
+
});
|
|
136
|
+
// 3️⃣ Serve /src/* files (on-the-fly transform)
|
|
137
|
+
app.use(async (req, res, next) => {
|
|
138
|
+
if (!req.url || !req.url.startsWith('/src/'))
|
|
139
|
+
return next();
|
|
143
140
|
try {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
res.
|
|
166
|
-
res.end(JSON.stringify({ ...pos, snippet }));
|
|
141
|
+
const filePath = path_1.default.join(appRoot, decodeURIComponent(req.url.split('?')[0]));
|
|
142
|
+
if (!(await fs_extra_1.default.pathExists(filePath)))
|
|
143
|
+
return next();
|
|
144
|
+
const code = await fs_extra_1.default.readFile(filePath, 'utf8');
|
|
145
|
+
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
146
|
+
let loader = 'js';
|
|
147
|
+
if (ext === '.ts')
|
|
148
|
+
loader = 'ts';
|
|
149
|
+
else if (ext === '.tsx')
|
|
150
|
+
loader = 'tsx';
|
|
151
|
+
else if (ext === '.jsx')
|
|
152
|
+
loader = 'jsx';
|
|
153
|
+
const transformed = await esbuild_1.default.transform(code, {
|
|
154
|
+
loader,
|
|
155
|
+
sourcemap: 'inline',
|
|
156
|
+
sourcefile: req.url,
|
|
157
|
+
target: 'es2020',
|
|
158
|
+
jsxFactory: 'React.createElement',
|
|
159
|
+
jsxFragment: 'React.Fragment',
|
|
160
|
+
});
|
|
161
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
162
|
+
res.end(transformed.code);
|
|
167
163
|
}
|
|
168
164
|
catch (err) {
|
|
169
165
|
const msg = err instanceof Error ? err.message : String(err);
|
|
166
|
+
console.error('Error serving src file:', msg);
|
|
170
167
|
res.writeHead(500);
|
|
171
|
-
res.end(
|
|
168
|
+
res.end(`// Error: ${msg}`);
|
|
172
169
|
}
|
|
173
170
|
});
|
|
174
171
|
// 4️⃣ Serve index.html with injected refresh + HMR
|
|
@@ -183,7 +180,6 @@ async function dev() {
|
|
|
183
180
|
html = html.replace('</body>', `
|
|
184
181
|
<script type="module">
|
|
185
182
|
import "/@react-refresh";
|
|
186
|
-
import "/@prismjs";
|
|
187
183
|
const ws = new WebSocket("ws://" + location.host);
|
|
188
184
|
ws.onmessage = async (e) => {
|
|
189
185
|
const msg = JSON.parse(e.data);
|
|
@@ -208,7 +204,6 @@ async function dev() {
|
|
|
208
204
|
res.end(html);
|
|
209
205
|
}
|
|
210
206
|
else {
|
|
211
|
-
// ✅ Serve compiled output files
|
|
212
207
|
const filePath = path_1.default.join(outDir, req.url || '');
|
|
213
208
|
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
214
209
|
const content = await fs_extra_1.default.readFile(filePath);
|
|
@@ -219,6 +214,7 @@ async function dev() {
|
|
|
219
214
|
next();
|
|
220
215
|
}
|
|
221
216
|
});
|
|
217
|
+
// 🔁 HMR via WebSocket
|
|
222
218
|
const server = http_1.default.createServer(app);
|
|
223
219
|
const wss = new ws_1.WebSocketServer({ server });
|
|
224
220
|
const broadcast = (data) => {
|
|
@@ -242,9 +238,9 @@ async function dev() {
|
|
|
242
238
|
});
|
|
243
239
|
server.listen(port, async () => {
|
|
244
240
|
const url = `http://localhost:${port}`;
|
|
245
|
-
console.log(chalk_1.default.
|
|
246
|
-
|
|
247
|
-
|
|
241
|
+
console.log(chalk_1.default.cyan.bold(`\n🚀 React Client Dev Server`));
|
|
242
|
+
console.log(chalk_1.default.gray('───────────────────────────────'));
|
|
243
|
+
console.log(chalk_1.default.green(`⚡ Running at: ${url}`));
|
|
248
244
|
await (0, open_1.default)(url, { newInstance: true });
|
|
249
245
|
});
|
|
250
246
|
process.on('SIGINT', async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
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",
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
]
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"@jridgewell/trace-mapping": "^0.3.31",
|
|
98
97
|
"chalk": "^4.1.2",
|
|
99
98
|
"chokidar": "^4.0.3",
|
|
100
99
|
"commander": "^14.0.2",
|