react-client 1.0.16 → 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.
@@ -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
- // Detect entry dynamically (main.tsx or main.jsx)
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
- // Detect open port
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
- // ⚔ React-refresh runtime auto install
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
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
65
- const _reactRefreshRuntime = safeResolveReactRefresh();
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
- const css = ${escaped};
75
- const style = document.createElement('style');
76
- style.textContent = css;
77
- document.head.appendChild(style);
78
- import.meta.hot && import.meta.hot.accept();
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
- // 🧱 Connect app
86
+ // 🌐 Connect app + caches
88
87
  const app = (0, connect_1.default)();
89
88
  const transformCache = new Map();
90
- // --- Prebundle persistent deps
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 msg = err instanceof Error ? err.message : String(err);
121
- console.warn(chalk_1.default.yellow(`āš ļø Skipped ${dep}: ${msg}`));
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
- const entryPath = require.resolve(id, { paths: [appRoot] });
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 msg = err instanceof Error ? err.message : String(err);
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}: ${msg}`);
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 filePath = path_1.default.join(appRoot, decodeURIComponent(req.url.split('?')[0]));
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,15 +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
- // 🧩 Rewrite bare imports (react, react-dom, etc.) to /@modules/*
202
+ // Rewrite bare imports → /@modules/*
178
203
  code = code
179
204
  .replace(/\bfrom\s+['"]([^'".\/][^'"]*)['"]/g, (_match, dep) => `from "/@modules/${dep}"`)
180
205
  .replace(/\bimport\(['"]([^'".\/][^'"]*)['"]\)/g, (_match, dep) => `import("/@modules/${dep}")`);
181
- // Run plugin transforms
182
- for (const p of plugins) {
206
+ for (const p of plugins)
183
207
  if (p.onTransform)
184
208
  code = await p.onTransform(code, filePath);
185
- }
186
209
  const ext = path_1.default.extname(filePath);
187
210
  let loader = 'js';
188
211
  if (ext === '.ts')
@@ -201,12 +224,13 @@ async function dev() {
201
224
  res.end(result.code);
202
225
  }
203
226
  catch (err) {
204
- const msg = err instanceof Error ? err.message : String(err);
227
+ const e = err;
228
+ console.error(chalk_1.default.red(`āš ļø Transform failed: ${e.message}`));
205
229
  res.writeHead(500);
206
- res.end(`// Error: ${msg}`);
230
+ res.end(`// Error: ${e.message}`);
207
231
  }
208
232
  });
209
- // --- Serve index.html with overlay + HMR client
233
+ // --- Serve index.html + overlay + HMR client
210
234
  app.use(async (req, res, next) => {
211
235
  if (req.url !== '/' && req.url !== '/index.html')
212
236
  return next();
@@ -261,7 +285,7 @@ async function dev() {
261
285
  console.log(chalk_1.default.yellow(`šŸ”„ Changed: ${file}`));
262
286
  transformCache.delete(file);
263
287
  for (const p of plugins) {
264
- p.onHotUpdate?.(file, {
288
+ await p.onHotUpdate?.(file, {
265
289
  broadcast: (msg) => broadcaster.broadcast(msg),
266
290
  });
267
291
  }
@@ -270,7 +294,7 @@ async function dev() {
270
294
  path: '/' + path_1.default.relative(appRoot, file).replace(/\\/g, '/'),
271
295
  });
272
296
  });
273
- // šŸš€ Launch
297
+ // šŸš€ Start server
274
298
  server.listen(port, async () => {
275
299
  const url = `http://localhost:${port}`;
276
300
  console.log(chalk_1.default.cyan.bold('\nšŸš€ React Client Dev Server'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-client",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
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",