react-client 1.0.15 ā 1.0.17
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 +58 -29
- package/package.json +1 -1
package/dist/cli/commands/dev.js
CHANGED
|
@@ -24,7 +24,7 @@ async function dev() {
|
|
|
24
24
|
const defaultPort = userConfig.server?.port || 5173;
|
|
25
25
|
const cacheDir = path_1.default.join(appRoot, '.react-client', 'deps');
|
|
26
26
|
await fs_extra_1.default.ensureDir(cacheDir);
|
|
27
|
-
//
|
|
27
|
+
// š Dynamically detect entry (main.tsx or main.jsx)
|
|
28
28
|
const possibleEntries = ['src/main.tsx', 'src/main.jsx'];
|
|
29
29
|
const entry = possibleEntries.map((p) => path_1.default.join(appRoot, p)).find((p) => fs_extra_1.default.existsSync(p));
|
|
30
30
|
if (!entry) {
|
|
@@ -32,7 +32,7 @@ async function dev() {
|
|
|
32
32
|
process.exit(1);
|
|
33
33
|
}
|
|
34
34
|
const indexHtml = path_1.default.join(appRoot, 'index.html');
|
|
35
|
-
//
|
|
35
|
+
// š§ Port selection
|
|
36
36
|
const availablePort = await (0, detect_port_1.default)(defaultPort);
|
|
37
37
|
const port = availablePort;
|
|
38
38
|
if (availablePort !== defaultPort) {
|
|
@@ -47,7 +47,7 @@ async function dev() {
|
|
|
47
47
|
process.exit(0);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
// ā”
|
|
50
|
+
// ā” Ensure react-refresh runtime installed
|
|
51
51
|
function safeResolveReactRefresh() {
|
|
52
52
|
try {
|
|
53
53
|
return require.resolve('react-refresh/runtime');
|
|
@@ -61,9 +61,8 @@ async function dev() {
|
|
|
61
61
|
return require.resolve('react-refresh/runtime');
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// --- Plugins (core + user)
|
|
64
|
+
void safeResolveReactRefresh();
|
|
65
|
+
// š§© Core + user plugins
|
|
67
66
|
const corePlugins = [
|
|
68
67
|
{
|
|
69
68
|
name: 'css-hmr',
|
|
@@ -71,12 +70,12 @@ async function dev() {
|
|
|
71
70
|
if (id.endsWith('.css')) {
|
|
72
71
|
const escaped = JSON.stringify(code);
|
|
73
72
|
return `
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
const css = ${escaped};
|
|
74
|
+
const style = document.createElement('style');
|
|
75
|
+
style.textContent = css;
|
|
76
|
+
document.head.appendChild(style);
|
|
77
|
+
import.meta.hot && import.meta.hot.accept();
|
|
78
|
+
`;
|
|
80
79
|
}
|
|
81
80
|
return code;
|
|
82
81
|
},
|
|
@@ -84,10 +83,10 @@ async function dev() {
|
|
|
84
83
|
];
|
|
85
84
|
const userPlugins = Array.isArray(userConfig.plugins) ? userConfig.plugins : [];
|
|
86
85
|
const plugins = [...corePlugins, ...userPlugins];
|
|
87
|
-
//
|
|
86
|
+
// š Connect app + caches
|
|
88
87
|
const app = (0, connect_1.default)();
|
|
89
88
|
const transformCache = new Map();
|
|
90
|
-
//
|
|
89
|
+
// š¦ Prebundle persistent deps
|
|
91
90
|
async function prebundleDeps() {
|
|
92
91
|
const pkgFile = path_1.default.join(appRoot, 'package.json');
|
|
93
92
|
if (!fs_extra_1.default.existsSync(pkgFile))
|
|
@@ -117,13 +116,13 @@ async function dev() {
|
|
|
117
116
|
console.log(chalk_1.default.green(`ā
Cached ${dep}`));
|
|
118
117
|
}
|
|
119
118
|
catch (err) {
|
|
120
|
-
const
|
|
121
|
-
console.warn(chalk_1.default.yellow(`ā ļø Skipped ${dep}: ${
|
|
119
|
+
const e = err;
|
|
120
|
+
console.warn(chalk_1.default.yellow(`ā ļø Skipped ${dep}: ${e.message}`));
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
123
|
}
|
|
125
124
|
await prebundleDeps();
|
|
126
|
-
// --- Serve prebundled modules
|
|
125
|
+
// --- Serve prebundled modules (fixed resolver)
|
|
127
126
|
app.use('/@modules/', async (req, res, next) => {
|
|
128
127
|
const id = req.url?.replace(/^\/@modules\//, '');
|
|
129
128
|
if (!id)
|
|
@@ -134,7 +133,23 @@ async function dev() {
|
|
|
134
133
|
res.setHeader('Content-Type', 'application/javascript');
|
|
135
134
|
return res.end(await fs_extra_1.default.readFile(cacheFile));
|
|
136
135
|
}
|
|
137
|
-
|
|
136
|
+
let entryPath = null;
|
|
137
|
+
try {
|
|
138
|
+
entryPath = require.resolve(id, { paths: [path_1.default.join(appRoot, 'node_modules')] });
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
try {
|
|
142
|
+
entryPath = require.resolve(id, { paths: [root] });
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
if (id === 'react')
|
|
146
|
+
entryPath = require.resolve('react');
|
|
147
|
+
else if (id === 'react-dom' || id === 'react-dom/client')
|
|
148
|
+
entryPath = require.resolve('react-dom');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (!entryPath)
|
|
152
|
+
throw new Error(`Could not resolve ${id}`);
|
|
138
153
|
const result = await esbuild_1.default.build({
|
|
139
154
|
entryPoints: [entryPath],
|
|
140
155
|
bundle: true,
|
|
@@ -144,6 +159,7 @@ async function dev() {
|
|
|
144
159
|
write: false,
|
|
145
160
|
});
|
|
146
161
|
let code = result.outputFiles[0].text;
|
|
162
|
+
// ā
Fix for react-dom/client exports
|
|
147
163
|
if (id === 'react-dom/client') {
|
|
148
164
|
code += `
|
|
149
165
|
import * as ReactDOMClient from '/@modules/react-dom';
|
|
@@ -156,16 +172,25 @@ async function dev() {
|
|
|
156
172
|
res.end(code);
|
|
157
173
|
}
|
|
158
174
|
catch (err) {
|
|
159
|
-
const
|
|
175
|
+
const e = err;
|
|
176
|
+
console.error(chalk_1.default.red(`ā Failed to load module ${id}: ${e.message}`));
|
|
160
177
|
res.writeHead(500);
|
|
161
|
-
res.end(`// Failed to resolve module ${id}: ${
|
|
178
|
+
res.end(`// Failed to resolve module ${id}: ${e.message}`);
|
|
162
179
|
}
|
|
163
180
|
});
|
|
164
|
-
// --- Serve /src files dynamically
|
|
181
|
+
// --- Serve /src files dynamically (auto extension fallback)
|
|
165
182
|
app.use(async (req, res, next) => {
|
|
166
183
|
if (!req.url || (!req.url.startsWith('/src/') && !req.url.endsWith('.css')))
|
|
167
184
|
return next();
|
|
168
|
-
const
|
|
185
|
+
const rawPath = decodeURIComponent(req.url.split('?')[0]);
|
|
186
|
+
let filePath = path_1.default.join(appRoot, rawPath);
|
|
187
|
+
const possibleExts = ['', '.tsx', '.ts', '.jsx', '.js'];
|
|
188
|
+
for (const ext of possibleExts) {
|
|
189
|
+
if (await fs_extra_1.default.pathExists(filePath + ext)) {
|
|
190
|
+
filePath += ext;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
169
194
|
if (!(await fs_extra_1.default.pathExists(filePath)))
|
|
170
195
|
return next();
|
|
171
196
|
try {
|
|
@@ -174,10 +199,13 @@ async function dev() {
|
|
|
174
199
|
return res.end(transformCache.get(filePath));
|
|
175
200
|
}
|
|
176
201
|
let code = await fs_extra_1.default.readFile(filePath, 'utf8');
|
|
177
|
-
|
|
202
|
+
// Rewrite bare imports ā /@modules/*
|
|
203
|
+
code = code
|
|
204
|
+
.replace(/\bfrom\s+['"]([^'".\/][^'"]*)['"]/g, (_match, dep) => `from "/@modules/${dep}"`)
|
|
205
|
+
.replace(/\bimport\(['"]([^'".\/][^'"]*)['"]\)/g, (_match, dep) => `import("/@modules/${dep}")`);
|
|
206
|
+
for (const p of plugins)
|
|
178
207
|
if (p.onTransform)
|
|
179
208
|
code = await p.onTransform(code, filePath);
|
|
180
|
-
}
|
|
181
209
|
const ext = path_1.default.extname(filePath);
|
|
182
210
|
let loader = 'js';
|
|
183
211
|
if (ext === '.ts')
|
|
@@ -196,12 +224,13 @@ async function dev() {
|
|
|
196
224
|
res.end(result.code);
|
|
197
225
|
}
|
|
198
226
|
catch (err) {
|
|
199
|
-
const
|
|
227
|
+
const e = err;
|
|
228
|
+
console.error(chalk_1.default.red(`ā ļø Transform failed: ${e.message}`));
|
|
200
229
|
res.writeHead(500);
|
|
201
|
-
res.end(`// Error: ${
|
|
230
|
+
res.end(`// Error: ${e.message}`);
|
|
202
231
|
}
|
|
203
232
|
});
|
|
204
|
-
// --- Serve index.html
|
|
233
|
+
// --- Serve index.html + overlay + HMR client
|
|
205
234
|
app.use(async (req, res, next) => {
|
|
206
235
|
if (req.url !== '/' && req.url !== '/index.html')
|
|
207
236
|
return next();
|
|
@@ -256,7 +285,7 @@ async function dev() {
|
|
|
256
285
|
console.log(chalk_1.default.yellow(`š Changed: ${file}`));
|
|
257
286
|
transformCache.delete(file);
|
|
258
287
|
for (const p of plugins) {
|
|
259
|
-
p.onHotUpdate?.(file, {
|
|
288
|
+
await p.onHotUpdate?.(file, {
|
|
260
289
|
broadcast: (msg) => broadcaster.broadcast(msg),
|
|
261
290
|
});
|
|
262
291
|
}
|
|
@@ -265,7 +294,7 @@ async function dev() {
|
|
|
265
294
|
path: '/' + path_1.default.relative(appRoot, file).replace(/\\/g, '/'),
|
|
266
295
|
});
|
|
267
296
|
});
|
|
268
|
-
// š
|
|
297
|
+
// š Start server
|
|
269
298
|
server.listen(port, async () => {
|
|
270
299
|
const url = `http://localhost:${port}`;
|
|
271
300
|
console.log(chalk_1.default.cyan.bold('\nš React Client Dev Server'));
|