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.
@@ -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
- const entry = path_1.default.join(appRoot, 'src', 'main.tsx');
29
- const indexHtml = path_1.default.join(appRoot, 'index.html');
30
- if (!fs_extra_1.default.existsSync(entry)) {
31
- console.error(chalk_1.default.red('❌ Entry not found: src/main.tsx'));
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]', // ✅ output main.js (not src/main.js)
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️⃣ Serve PrismJS for code highlighting (overlay)
112
- app.use('/@prismjs', async (_req, res) => {
113
- const prismPath = require.resolve('prismjs/prism.js');
114
- const css = await fs_extra_1.default.readFile(require.resolve('prismjs/themes/prism-tomorrow.css'), 'utf8');
115
- const js = await fs_extra_1.default.readFile(prismPath, 'utf8');
116
- res.setHeader('Content-Type', 'application/javascript');
117
- res.end(`
118
- (function(){
119
- const style = document.createElement('style');
120
- style.textContent = \`${css}\`;
121
- document.head.appendChild(style);
122
- ${js}
123
- })();
124
- `);
125
- });
126
- // 3️⃣ Source map resolver (for overlay stack trace)
127
- app.use('/@source-map', async (req, res) => {
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
- const mapPath = path_1.default.join(outDir, file + '.map');
138
- if (!fs_extra_1.default.existsSync(mapPath)) {
139
- res.writeHead(404);
140
- res.end('Map not found');
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 mapJson = JSON.parse(await fs_extra_1.default.readFile(mapPath, 'utf8'));
145
- const traceMap = new trace_mapping_1.TraceMap(mapJson);
146
- const pos = (0, trace_mapping_1.originalPositionFor)(traceMap, { line, column });
147
- if (!pos.source) {
148
- res.writeHead(404);
149
- res.end('Source not found');
150
- return;
151
- }
152
- const absSource = path_1.default.resolve(outDir, '../', pos.source);
153
- let snippet = '';
154
- if (await fs_extra_1.default.pathExists(absSource)) {
155
- const lines = (await fs_extra_1.default.readFile(absSource, 'utf8')).split('\n');
156
- const start = Math.max((pos.line || 1) - 3, 0);
157
- const end = Math.min(lines.length, (pos.line || 1) + 2);
158
- snippet = lines
159
- .slice(start, end)
160
- .map((l, i) => `<span class="line-number">${start + i + 1}</span> ${l
161
- .replace(/</g, '&lt;')
162
- .replace(/>/g, '&gt;')}`)
163
- .join('\\n');
164
- }
165
- res.setHeader('Content-Type', 'application/json');
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(JSON.stringify({ error: msg }));
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.green(`\n Dev Server running at ${url}`));
246
- if (port !== defaultPort)
247
- console.log(chalk_1.default.yellow(`⚠️ Using alternate port (default ${defaultPort} was occupied).`));
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.10",
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",