what-compiler 0.5.1 → 0.5.4
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 +102 -0
- package/package.json +11 -3
- package/src/error-overlay.js +357 -0
- package/src/vite-plugin.js +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# what-compiler
|
|
2
|
+
|
|
3
|
+
JSX compiler for [What Framework](https://whatfw.com). Transforms JSX into optimized DOM operations via a Babel plugin, with a Vite plugin for seamless integration. Also provides file-based routing via `virtual:what-routes`.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install what-compiler --save-dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Vite Plugin
|
|
12
|
+
|
|
13
|
+
The recommended way to use the compiler. Add it to your Vite config:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
// vite.config.js
|
|
17
|
+
import { defineConfig } from 'vite';
|
|
18
|
+
import what from 'what-compiler/vite';
|
|
19
|
+
|
|
20
|
+
export default defineConfig({
|
|
21
|
+
plugins: [what()],
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Options
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
what({
|
|
29
|
+
include: /\.[jt]sx$/, // File extensions to process (default: .jsx/.tsx)
|
|
30
|
+
exclude: /node_modules/, // Files to exclude (default: node_modules)
|
|
31
|
+
sourceMaps: true, // Enable source maps (default: true)
|
|
32
|
+
production: false, // Enable production optimizations (default: auto)
|
|
33
|
+
pages: 'src/pages', // Pages directory for file-based routing
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Babel Plugin
|
|
38
|
+
|
|
39
|
+
Use the Babel plugin directly for custom build setups:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
// babel.config.js
|
|
43
|
+
export default {
|
|
44
|
+
plugins: [
|
|
45
|
+
['what-compiler/babel', { production: false }],
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## File-Based Routing
|
|
51
|
+
|
|
52
|
+
The compiler scans a pages directory and generates a virtual routes module.
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
src/pages/
|
|
56
|
+
index.jsx -> /
|
|
57
|
+
about.jsx -> /about
|
|
58
|
+
blog/
|
|
59
|
+
index.jsx -> /blog
|
|
60
|
+
[slug].jsx -> /blog/:slug
|
|
61
|
+
[...all].jsx -> /*
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Import the generated routes in your app:
|
|
65
|
+
|
|
66
|
+
```jsx
|
|
67
|
+
import { routes } from 'virtual:what-routes';
|
|
68
|
+
import { FileRouter } from 'what-router';
|
|
69
|
+
import { mount } from 'what-framework';
|
|
70
|
+
|
|
71
|
+
mount(<FileRouter routes={routes} />, '#app');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Sub-path Exports
|
|
75
|
+
|
|
76
|
+
| Path | Contents |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `what-compiler` | All exports |
|
|
79
|
+
| `what-compiler/vite` | Vite plugin |
|
|
80
|
+
| `what-compiler/babel` | Babel plugin |
|
|
81
|
+
| `what-compiler/runtime` | Compiler runtime helpers |
|
|
82
|
+
| `what-compiler/file-router` | `scanPages`, `extractPageConfig`, `generateRoutesModule` |
|
|
83
|
+
|
|
84
|
+
## API
|
|
85
|
+
|
|
86
|
+
| Export | Description |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `vitePlugin(options?)` | Vite plugin for JSX transform and file routing |
|
|
89
|
+
| `what(options?)` | Named alias for the Vite plugin |
|
|
90
|
+
| `babelPlugin` | Babel plugin for JSX transformation |
|
|
91
|
+
| `scanPages(dir)` | Scan a directory for page files |
|
|
92
|
+
| `extractPageConfig(file)` | Extract page configuration from a file |
|
|
93
|
+
| `generateRoutesModule(pagesDir, rootDir)` | Generate a routes module string |
|
|
94
|
+
|
|
95
|
+
## Links
|
|
96
|
+
|
|
97
|
+
- [Documentation](https://whatfw.com)
|
|
98
|
+
- [GitHub](https://github.com/zvndev/what-fw)
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "what-compiler",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "JSX compiler for What Framework - transforms JSX to optimized DOM operations",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@babel/core": "^7.0.0",
|
|
26
|
-
"what-core": "^0.5.
|
|
26
|
+
"what-core": "^0.5.3"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"src"
|
|
@@ -31,5 +31,13 @@
|
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@babel/core": "^7.23.0",
|
|
33
33
|
"@babel/preset-env": "^7.23.0"
|
|
34
|
-
}
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/zvndev/what-fw"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/zvndev/what-fw/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://whatfw.com"
|
|
35
43
|
}
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Framework — Vite Error Overlay
|
|
3
|
+
*
|
|
4
|
+
* Custom error overlay injected during dev mode. Shows compiler transform errors
|
|
5
|
+
* and runtime signal errors with What Framework branding and helpful context.
|
|
6
|
+
*
|
|
7
|
+
* This is client-side code that Vite injects into the page during development.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// CSS for the overlay — scoped to avoid style conflicts
|
|
11
|
+
const OVERLAY_STYLES = `
|
|
12
|
+
:host {
|
|
13
|
+
position: fixed;
|
|
14
|
+
inset: 0;
|
|
15
|
+
z-index: 99999;
|
|
16
|
+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.backdrop {
|
|
20
|
+
position: fixed;
|
|
21
|
+
inset: 0;
|
|
22
|
+
background: rgba(0, 0, 0, 0.66);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.panel {
|
|
26
|
+
position: fixed;
|
|
27
|
+
inset: 2rem;
|
|
28
|
+
overflow: auto;
|
|
29
|
+
background: #1a1a2e;
|
|
30
|
+
border: 1px solid #2a2a4a;
|
|
31
|
+
border-radius: 12px;
|
|
32
|
+
box-shadow: 0 25px 80px rgba(0, 0, 0, 0.5);
|
|
33
|
+
color: #e0e0e0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.header {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: space-between;
|
|
40
|
+
padding: 1rem 1.5rem;
|
|
41
|
+
border-bottom: 1px solid #2a2a4a;
|
|
42
|
+
background: #16163a;
|
|
43
|
+
border-radius: 12px 12px 0 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.header-left {
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
gap: 0.75rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.logo {
|
|
53
|
+
width: 28px;
|
|
54
|
+
height: 28px;
|
|
55
|
+
background: linear-gradient(135deg, #2563eb, #1d4ed8);
|
|
56
|
+
border-radius: 6px;
|
|
57
|
+
display: grid;
|
|
58
|
+
place-items: center;
|
|
59
|
+
font-weight: 800;
|
|
60
|
+
font-size: 14px;
|
|
61
|
+
color: #fff;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.brand {
|
|
65
|
+
font-size: 14px;
|
|
66
|
+
font-weight: 600;
|
|
67
|
+
color: #a0a0c0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.tag {
|
|
71
|
+
font-size: 11px;
|
|
72
|
+
padding: 2px 8px;
|
|
73
|
+
border-radius: 4px;
|
|
74
|
+
font-weight: 600;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.tag-error {
|
|
78
|
+
background: #3b1219;
|
|
79
|
+
color: #f87171;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.tag-warning {
|
|
83
|
+
background: #3b2f19;
|
|
84
|
+
color: #fbbf24;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.close-btn {
|
|
88
|
+
background: none;
|
|
89
|
+
border: 1px solid #3a3a5a;
|
|
90
|
+
color: #a0a0c0;
|
|
91
|
+
border-radius: 6px;
|
|
92
|
+
padding: 4px 12px;
|
|
93
|
+
cursor: pointer;
|
|
94
|
+
font-family: inherit;
|
|
95
|
+
font-size: 12px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.close-btn:hover {
|
|
99
|
+
background: #2a2a4a;
|
|
100
|
+
color: #fff;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.body {
|
|
104
|
+
padding: 1.5rem;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.error-title {
|
|
108
|
+
font-size: 16px;
|
|
109
|
+
font-weight: 700;
|
|
110
|
+
color: #f87171;
|
|
111
|
+
margin: 0 0 0.5rem;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.error-message {
|
|
115
|
+
font-size: 14px;
|
|
116
|
+
color: #e0e0e0;
|
|
117
|
+
margin: 0 0 1rem;
|
|
118
|
+
line-height: 1.6;
|
|
119
|
+
white-space: pre-wrap;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.file-path {
|
|
123
|
+
display: inline-flex;
|
|
124
|
+
align-items: center;
|
|
125
|
+
gap: 0.5rem;
|
|
126
|
+
font-size: 12px;
|
|
127
|
+
color: #818cf8;
|
|
128
|
+
margin-bottom: 1rem;
|
|
129
|
+
padding: 0.25rem 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.code-frame {
|
|
133
|
+
background: #0d0d1a;
|
|
134
|
+
border: 1px solid #2a2a4a;
|
|
135
|
+
border-radius: 8px;
|
|
136
|
+
overflow-x: auto;
|
|
137
|
+
margin-bottom: 1rem;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.code-line {
|
|
141
|
+
display: flex;
|
|
142
|
+
padding: 0 1rem;
|
|
143
|
+
font-size: 13px;
|
|
144
|
+
line-height: 1.7;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.code-line.highlight {
|
|
148
|
+
background: rgba(248, 113, 113, 0.1);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.line-number {
|
|
152
|
+
color: #4a4a6a;
|
|
153
|
+
min-width: 3ch;
|
|
154
|
+
text-align: right;
|
|
155
|
+
margin-right: 1rem;
|
|
156
|
+
user-select: none;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.line-content {
|
|
160
|
+
white-space: pre;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.tip {
|
|
164
|
+
margin-top: 1rem;
|
|
165
|
+
padding: 0.75rem 1rem;
|
|
166
|
+
background: #1a2744;
|
|
167
|
+
border: 1px solid #1e3a5f;
|
|
168
|
+
border-radius: 8px;
|
|
169
|
+
font-size: 13px;
|
|
170
|
+
color: #93c5fd;
|
|
171
|
+
line-height: 1.5;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.tip-label {
|
|
175
|
+
font-weight: 700;
|
|
176
|
+
color: #60a5fa;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.stack {
|
|
180
|
+
margin-top: 1rem;
|
|
181
|
+
font-size: 12px;
|
|
182
|
+
color: #6a6a8a;
|
|
183
|
+
white-space: pre-wrap;
|
|
184
|
+
line-height: 1.5;
|
|
185
|
+
}
|
|
186
|
+
`;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Build the overlay HTML for an error
|
|
190
|
+
*/
|
|
191
|
+
function buildOverlayHTML(err) {
|
|
192
|
+
const isCompilerError = err._isCompilerError || err.plugin === 'vite-plugin-what';
|
|
193
|
+
const type = isCompilerError ? 'Compiler Error' : 'Runtime Error';
|
|
194
|
+
const tagClass = isCompilerError ? 'tag-error' : 'tag-warning';
|
|
195
|
+
|
|
196
|
+
let codeFrame = '';
|
|
197
|
+
if (err.frame || err._frame) {
|
|
198
|
+
const frame = err.frame || err._frame;
|
|
199
|
+
const lines = frame.split('\n');
|
|
200
|
+
codeFrame = `<div class="code-frame">${
|
|
201
|
+
lines.map(line => {
|
|
202
|
+
const isHighlight = line.trimStart().startsWith('>');
|
|
203
|
+
const cleaned = line.replace(/^\s*>\s?/, ' ').replace(/^\s{2}/, '');
|
|
204
|
+
const match = cleaned.match(/^(\s*\d+)\s*\|(.*)$/);
|
|
205
|
+
if (match) {
|
|
206
|
+
return `<div class="code-line${isHighlight ? ' highlight' : ''}"><span class="line-number">${match[1].trim()}</span><span class="line-content">${escapeHTML(match[2])}</span></div>`;
|
|
207
|
+
}
|
|
208
|
+
// Caret line (^^^)
|
|
209
|
+
if (cleaned.trim().startsWith('|')) {
|
|
210
|
+
return `<div class="code-line highlight"><span class="line-number"></span><span class="line-content" style="color:#f87171">${escapeHTML(cleaned.replace(/^\s*\|/, ''))}</span></div>`;
|
|
211
|
+
}
|
|
212
|
+
return '';
|
|
213
|
+
}).join('')
|
|
214
|
+
}</div>`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const filePath = err.id || err.loc?.file || '';
|
|
218
|
+
const line = err.loc?.line ?? '';
|
|
219
|
+
const col = err.loc?.column ?? '';
|
|
220
|
+
const location = filePath
|
|
221
|
+
? `<div class="file-path">${escapeHTML(filePath)}${line ? `:${line}` : ''}${col ? `:${col}` : ''}</div>`
|
|
222
|
+
: '';
|
|
223
|
+
|
|
224
|
+
const tip = getTip(err);
|
|
225
|
+
const tipHTML = tip ? `<div class="tip"><span class="tip-label">Tip: </span>${escapeHTML(tip)}</div>` : '';
|
|
226
|
+
|
|
227
|
+
const stack = err.stack && !isCompilerError
|
|
228
|
+
? `<div class="stack">${escapeHTML(cleanStack(err.stack))}</div>`
|
|
229
|
+
: '';
|
|
230
|
+
|
|
231
|
+
return `
|
|
232
|
+
<div class="backdrop"></div>
|
|
233
|
+
<div class="panel">
|
|
234
|
+
<div class="header">
|
|
235
|
+
<div class="header-left">
|
|
236
|
+
<div class="logo">W</div>
|
|
237
|
+
<span class="brand">What Framework</span>
|
|
238
|
+
<span class="tag ${tagClass}">${type}</span>
|
|
239
|
+
</div>
|
|
240
|
+
<button class="close-btn">Dismiss (Esc)</button>
|
|
241
|
+
</div>
|
|
242
|
+
<div class="body">
|
|
243
|
+
<h2 class="error-title">${escapeHTML(err.name || 'Error')}</h2>
|
|
244
|
+
${location}
|
|
245
|
+
<pre class="error-message">${escapeHTML(err.message || String(err))}</pre>
|
|
246
|
+
${codeFrame}
|
|
247
|
+
${tipHTML}
|
|
248
|
+
${stack}
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Context-aware tips for common What Framework errors
|
|
256
|
+
*/
|
|
257
|
+
function getTip(err) {
|
|
258
|
+
const msg = (err.message || '').toLowerCase();
|
|
259
|
+
|
|
260
|
+
if (msg.includes('infinite') && msg.includes('effect')) {
|
|
261
|
+
return 'An effect is writing to a signal it also reads. Use untrack() to read without subscribing, or move the write to a different effect.';
|
|
262
|
+
}
|
|
263
|
+
if (msg.includes('jsx') && msg.includes('unexpected')) {
|
|
264
|
+
return 'Make sure your vite.config includes the What compiler plugin: import what from "what-compiler/vite"';
|
|
265
|
+
}
|
|
266
|
+
if (msg.includes('not a function') && msg.includes('signal')) {
|
|
267
|
+
return 'Signals are functions: call sig() to read, sig(value) to write. Check you\'re not destructuring a signal.';
|
|
268
|
+
}
|
|
269
|
+
if (msg.includes('hydrat')) {
|
|
270
|
+
return 'Hydration mismatches happen when SSR output differs from client render. Ensure server and client see the same initial state.';
|
|
271
|
+
}
|
|
272
|
+
return '';
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function escapeHTML(str) {
|
|
276
|
+
return str
|
|
277
|
+
.replace(/&/g, '&')
|
|
278
|
+
.replace(/</g, '<')
|
|
279
|
+
.replace(/>/g, '>')
|
|
280
|
+
.replace(/"/g, '"');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function cleanStack(stack) {
|
|
284
|
+
return stack
|
|
285
|
+
.split('\n')
|
|
286
|
+
.filter(line => !line.includes('node_modules'))
|
|
287
|
+
.slice(0, 10)
|
|
288
|
+
.join('\n');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Client-side overlay component — injected as a custom element
|
|
293
|
+
* to avoid style conflicts with the user's application.
|
|
294
|
+
*/
|
|
295
|
+
const OVERLAY_ELEMENT = `
|
|
296
|
+
class WhatErrorOverlay extends HTMLElement {
|
|
297
|
+
constructor(err) {
|
|
298
|
+
super();
|
|
299
|
+
this.root = this.attachShadow({ mode: 'open' });
|
|
300
|
+
this.root.innerHTML = \`<style>${OVERLAY_STYLES}</style>\`;
|
|
301
|
+
this.show(err);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
show(err) {
|
|
305
|
+
const template = document.createElement('template');
|
|
306
|
+
template.innerHTML = (${buildOverlayHTML.toString()})(err);
|
|
307
|
+
this.root.appendChild(template.content.cloneNode(true));
|
|
308
|
+
|
|
309
|
+
// Close handlers
|
|
310
|
+
this.root.querySelector('.close-btn')?.addEventListener('click', () => this.close());
|
|
311
|
+
this.root.querySelector('.backdrop')?.addEventListener('click', () => this.close());
|
|
312
|
+
document.addEventListener('keydown', this._onKey = (e) => {
|
|
313
|
+
if (e.key === 'Escape') this.close();
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
close() {
|
|
318
|
+
document.removeEventListener('keydown', this._onKey);
|
|
319
|
+
this.remove();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Helper functions bundled into the overlay element
|
|
324
|
+
${escapeHTML.toString()}
|
|
325
|
+
${cleanStack.toString()}
|
|
326
|
+
${getTip.toString()}
|
|
327
|
+
|
|
328
|
+
if (!customElements.get('what-error-overlay')) {
|
|
329
|
+
customElements.define('what-error-overlay', WhatErrorOverlay);
|
|
330
|
+
}
|
|
331
|
+
`;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Generate the client-side error overlay injection script.
|
|
335
|
+
* Called by the Vite plugin to inject into the dev server.
|
|
336
|
+
*/
|
|
337
|
+
export function getErrorOverlayCode() {
|
|
338
|
+
return OVERLAY_ELEMENT;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Create the error overlay middleware for Vite's dev server.
|
|
343
|
+
* Intercepts Vite's error events and shows a custom What-branded overlay.
|
|
344
|
+
*/
|
|
345
|
+
export function setupErrorOverlay(server) {
|
|
346
|
+
// Listen for Vite errors and enrich with What Framework context
|
|
347
|
+
const origSend = server.ws.send.bind(server.ws);
|
|
348
|
+
server.ws.send = function (payload) {
|
|
349
|
+
if (payload?.type === 'error') {
|
|
350
|
+
// Tag compiler errors
|
|
351
|
+
if (payload.err?.plugin === 'vite-plugin-what') {
|
|
352
|
+
payload.err._isCompilerError = true;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return origSend(payload);
|
|
356
|
+
};
|
|
357
|
+
}
|
package/src/vite-plugin.js
CHANGED
|
@@ -10,6 +10,7 @@ import path from 'path';
|
|
|
10
10
|
import { transformSync } from '@babel/core';
|
|
11
11
|
import whatBabelPlugin from './babel-plugin.js';
|
|
12
12
|
import { generateRoutesModule, scanPages } from './file-router.js';
|
|
13
|
+
import { setupErrorOverlay } from './error-overlay.js';
|
|
13
14
|
|
|
14
15
|
const VIRTUAL_ROUTES_ID = 'virtual:what-routes';
|
|
15
16
|
const RESOLVED_VIRTUAL_ID = '\0' + VIRTUAL_ROUTES_ID;
|
|
@@ -43,6 +44,9 @@ export default function whatVitePlugin(options = {}) {
|
|
|
43
44
|
configureServer(devServer) {
|
|
44
45
|
server = devServer;
|
|
45
46
|
|
|
47
|
+
// Set up What-branded error overlay
|
|
48
|
+
setupErrorOverlay(devServer);
|
|
49
|
+
|
|
46
50
|
// Watch the pages directory for file additions/removals
|
|
47
51
|
devServer.watcher.on('add', (file) => {
|
|
48
52
|
if (file.startsWith(pagesDir)) {
|
|
@@ -107,6 +111,12 @@ export default function whatVitePlugin(options = {}) {
|
|
|
107
111
|
map: result.map
|
|
108
112
|
};
|
|
109
113
|
} catch (error) {
|
|
114
|
+
// Enrich Babel errors with file context for the error overlay
|
|
115
|
+
error.plugin = 'vite-plugin-what';
|
|
116
|
+
if (!error.id) error.id = id;
|
|
117
|
+
if (error.loc === undefined && error._loc) {
|
|
118
|
+
error.loc = { file: id, line: error._loc.line, column: error._loc.column };
|
|
119
|
+
}
|
|
110
120
|
console.error(`[what] Error transforming ${id}:`, error.message);
|
|
111
121
|
throw error;
|
|
112
122
|
}
|