mono-jsx 0.0.0 β 0.1.0
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/LICENSE +21 -0
- package/README.md +435 -0
- package/bin/mono-jsx +34 -0
- package/index.mjs +2 -0
- package/jsx-runtime.mjs +692 -0
- package/package.json +34 -2
- package/types/aria.d.ts +329 -0
- package/types/css.d.ts +12137 -0
- package/types/html.d.ts +1099 -0
- package/types/jsx-runtime.d.ts +7 -0
- package/types/jsx.d.ts +37 -0
- package/types/mono.d.ts +105 -0
- package/types/render.d.ts +13 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Je Xia <i@jex.me>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# mono-jsx
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
mono-jsx is a JSX runtime that renders `<html>` element to a `Response` object in JavaScript runtimes like Node.js, Deno, Bun, Cloudflare Workers, etc.
|
|
6
|
+
|
|
7
|
+
- π No build step needed
|
|
8
|
+
- π¦ Lightweight(8KB gzipped), zero dependencies
|
|
9
|
+
- π« Minimal state runtime
|
|
10
|
+
- π¨ Full Web API types
|
|
11
|
+
- β³ Streaming rendering
|
|
12
|
+
- π Universal, works in Node.js, Deno, Bun, Cloudflare Workers, etc.
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
export default {
|
|
16
|
+
fetch: (req) => (
|
|
17
|
+
<html>
|
|
18
|
+
<h1>Hello World!</h1>
|
|
19
|
+
</html>
|
|
20
|
+
),
|
|
21
|
+
};
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
mono-jsx supports all modern JavaScript runtimes including Node.js, Deno, Bun, Cloudflare Workers, etc.
|
|
27
|
+
You can install it via `npm i`, `deno add`, or `bun add`.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Node.js, Cloudflare Workers, or other node-compatible runtimes
|
|
31
|
+
npm i mono-jsx
|
|
32
|
+
# Deno
|
|
33
|
+
deno add npm:mono-jsx
|
|
34
|
+
# Bun
|
|
35
|
+
bun add mono-jsx
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Setup JSX Runtime
|
|
39
|
+
|
|
40
|
+
To use mono-jsx as JSX runtime, add the following configuration to your `tsconfig.json`(`deno.json` for Deno):
|
|
41
|
+
|
|
42
|
+
```jsonc
|
|
43
|
+
{
|
|
44
|
+
"compilerOptions": {
|
|
45
|
+
"jsx": "react-jsx",
|
|
46
|
+
"jsxImportSource": "mono-jsx",
|
|
47
|
+
"allowJs": true // required for supporting `.jsx` extension in Node.js
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Alternatively, you can also use pragma directive in your JSX file.
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
/** @jsxImportSource mono-jsx */
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
You can also run `mono-jsx setup` to automatically add the configuration to your `tsconfig.json` or `deno.json`.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Node.js, Cloudflare Workers, or other node-compatible runtimes
|
|
62
|
+
npx mono-jsx setup
|
|
63
|
+
# Deno
|
|
64
|
+
deno run npm:mono-jsx setup
|
|
65
|
+
# Bun
|
|
66
|
+
bunx mono-jsx setup
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
To create a html response in server-side, you just need to return a `<html>` element in the `fetch` handler.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
// app.tsx
|
|
75
|
+
|
|
76
|
+
export default {
|
|
77
|
+
fetch: (req) => (
|
|
78
|
+
<html>
|
|
79
|
+
<h1>Hello World!</h1>
|
|
80
|
+
</html>
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
For Deno/Bun users, you can run the `app.tsx` directly.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
deno serve app.tsx
|
|
89
|
+
bun run app.tsx
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If you are building a web app with [Cloudflare Workers](https://developers.cloudflare.com/workers/wrangler/commands/#dev), use `wrangler dev` command to start the app in local development mode.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx wrangler dev app.tsx
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Node.js does not support JSX syntax and declarative fetch server**, we recommend using mono-jsx with [srvx](https://srvx.h3.dev/).
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
// app.tsx
|
|
102
|
+
|
|
103
|
+
import { serve } from "srvx";
|
|
104
|
+
|
|
105
|
+
serve({
|
|
106
|
+
port: 3000,
|
|
107
|
+
fetch: (req) => (
|
|
108
|
+
<html>
|
|
109
|
+
<h1>Hello World!</h1>
|
|
110
|
+
</html>
|
|
111
|
+
),
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
and you will need [tsx](https://www.npmjs.com/package/tsx) to start the app.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npx tsx app.tsx
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Using JSX
|
|
122
|
+
|
|
123
|
+
mono-jsx uses [**JSX**](https://react.dev/learn/describing-the-ui) to describe the user interface, similar to React but with some differences.
|
|
124
|
+
|
|
125
|
+
### Using Standard HTML Property Names
|
|
126
|
+
|
|
127
|
+
mono-jsx uses standard HTML property names instead of React's overthinked property names.
|
|
128
|
+
|
|
129
|
+
- `className` -> `class`
|
|
130
|
+
- `htmlFor` -> `for`
|
|
131
|
+
- `onChange` -> `onInput`
|
|
132
|
+
|
|
133
|
+
### Composition `class`
|
|
134
|
+
|
|
135
|
+
mono-jsx allows you to compose the `class` property using an array of strings, objects, or expressions.
|
|
136
|
+
|
|
137
|
+
```jsx
|
|
138
|
+
<div class={["container box", isActive && "active", { hover: isHover }]} />;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Using Pseudo Classes and Media Queries in the `style` Property
|
|
142
|
+
|
|
143
|
+
mono-jsx allows you to use [pseudo classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes), [pseudo elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements), [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries), and [css nesting](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting) in the `style` property.
|
|
144
|
+
|
|
145
|
+
```jsx
|
|
146
|
+
<a
|
|
147
|
+
style={{
|
|
148
|
+
color: "black",
|
|
149
|
+
"::after": { content: "β©οΈ" },
|
|
150
|
+
":hover": { textDecoration: "underline" },
|
|
151
|
+
"@media (prefers-color-scheme: dark)": { color: "white" },
|
|
152
|
+
"& .icon": { width: "1em", height: "1em", marginRight: "0.5em" },
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
<img class="icon" src="link.png" />
|
|
156
|
+
Link
|
|
157
|
+
</a>;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `<slot>` Element
|
|
161
|
+
|
|
162
|
+
mono-jsx uses [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot) element to render the slotted content(Equivalent to React's `children` proptery). Plus, you also can add the `name` attribute to define a named slot.
|
|
163
|
+
|
|
164
|
+
```jsx
|
|
165
|
+
function Container() {
|
|
166
|
+
return (
|
|
167
|
+
<div class="container">
|
|
168
|
+
<slot /> {/* <h1>Hello world!</h1> */}
|
|
169
|
+
<slot name="desc" /> {/* <p>This is a description.</p> */}
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function App() {
|
|
175
|
+
return (
|
|
176
|
+
<Container>
|
|
177
|
+
<p slot="desc">This is a description.</p>
|
|
178
|
+
<h1>Hello world!</h1>
|
|
179
|
+
</Container>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### `html` Tag Function
|
|
185
|
+
|
|
186
|
+
mono-jsx doesn't support the `dangerouslySetInnerHTML` property, instead, it provides a `html` tag function to render raw HTML in JSX.
|
|
187
|
+
|
|
188
|
+
```jsx
|
|
189
|
+
function App() {
|
|
190
|
+
return <div>{html`<h1>Hello world!</h1>`}</div>;
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The `html` tag function is a global function injected by mono-jsx, you can use it in any JSX expression without importing it.
|
|
195
|
+
You also can use the `css` and `js`, that are just aliases of the `html` tag function, to render CSS and JavaScript code.
|
|
196
|
+
|
|
197
|
+
```jsx
|
|
198
|
+
function App() {
|
|
199
|
+
return (
|
|
200
|
+
<head>
|
|
201
|
+
<style>{css`h1 { font-size: 3rem; }`}</style>
|
|
202
|
+
<script>{js`console.log("Hello world!")`}</script>
|
|
203
|
+
</head>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
> [!WARNING]
|
|
209
|
+
> the `html` tag function is **unsafe** that can cause [**XSS**](https://en.wikipedia.org/wiki/Cross-site_scripting) vulnerabilities.
|
|
210
|
+
|
|
211
|
+
### Event Handlers
|
|
212
|
+
|
|
213
|
+
mono-jsx allows you to write event handlers directly in the JSX code, like React.
|
|
214
|
+
|
|
215
|
+
```jsx
|
|
216
|
+
function Button() {
|
|
217
|
+
return <button onClick={(evt) => alert("BOOM!")}>Click Me</button>;
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
> [!NOTE]
|
|
222
|
+
> the event handler would never be called in server-side. Instead it will be serialized to a string and sent to the client-side. **This means you should NOT use any server-side variables or functions in the event handler.**
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
function Button(this: FC, props: { role: string }) {
|
|
226
|
+
let message = "BOOM!";
|
|
227
|
+
console.log(message); // only print message in server-side
|
|
228
|
+
return (
|
|
229
|
+
<button
|
|
230
|
+
role={props.role}
|
|
231
|
+
onClick={(evt) => {
|
|
232
|
+
alert(message); // β `message` is a server-side variable
|
|
233
|
+
console.log(props.role); // β `props` is a server-side variable
|
|
234
|
+
Deno.exit(0); // β `Deno` is unavailable in the browser
|
|
235
|
+
document.title = "BOOM!"; // β
`document` is a browser API
|
|
236
|
+
console.log(evt.target); // β
`evt` is the event object
|
|
237
|
+
this.count++; // β
update the state `count`
|
|
238
|
+
}}
|
|
239
|
+
>
|
|
240
|
+
Click Me
|
|
241
|
+
</button>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Plus, mono-jsx supports the `mount` event that will be triggered when the element is mounted in the client-side.
|
|
247
|
+
|
|
248
|
+
```jsx
|
|
249
|
+
function App() {
|
|
250
|
+
return (
|
|
251
|
+
<div onMount={(evt) => console.log(evt.target, "Mounted!")}>
|
|
252
|
+
<h1>Hello World!</h1>
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Using State
|
|
259
|
+
|
|
260
|
+
mono-jsx provides a minimal state runtime that allows you to update view based on state changes in client-side.
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
function App(
|
|
264
|
+
this: FC<{ count: number }>,
|
|
265
|
+
props: { initialCount?: number },
|
|
266
|
+
) {
|
|
267
|
+
this.count = props.initialCount ?? 0;
|
|
268
|
+
return (
|
|
269
|
+
<div>
|
|
270
|
+
{/* use the state */}
|
|
271
|
+
<span>{this.count}</span>
|
|
272
|
+
{/* use computed state */}
|
|
273
|
+
<span>doubled: {this.computed(() => 2 * this.count)}</span>
|
|
274
|
+
{/* update the state in event handlers */}
|
|
275
|
+
<button onClick={() => this.count--}>-</button>
|
|
276
|
+
<button onClick={() => this.count++}>+</button>
|
|
277
|
+
</div>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
> [!WARNING]
|
|
283
|
+
> The state cannot be used in an arrow function component, you should use a `function` declaration instead.
|
|
284
|
+
|
|
285
|
+
```jsx
|
|
286
|
+
// β `this.count++` won't update the view, please use a function declaration instead
|
|
287
|
+
const App = () => {
|
|
288
|
+
this.count = 0;
|
|
289
|
+
return (
|
|
290
|
+
<div>
|
|
291
|
+
<span>{this.count}</span>
|
|
292
|
+
<button onClick={() => this.count++}>+</button>
|
|
293
|
+
</div>
|
|
294
|
+
);
|
|
295
|
+
};
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Built-in Elements
|
|
299
|
+
|
|
300
|
+
mono-jsx provides some built-in elements to help you build your app.
|
|
301
|
+
|
|
302
|
+
### `<toggle>` element
|
|
303
|
+
|
|
304
|
+
`<toggle>` element allows you to toggle the visibility of the slotted content.
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
function App(this: FC<{ show: boolean }>) {
|
|
308
|
+
this.show = false;
|
|
309
|
+
return (
|
|
310
|
+
<div>
|
|
311
|
+
<toggle value={this.show}>
|
|
312
|
+
<h1>Hello World!</h1>
|
|
313
|
+
</toggle>
|
|
314
|
+
<button onClick={toggle}>{this.computed(() => this.show ? "Hide" : "Show")}</button>
|
|
315
|
+
</div>
|
|
316
|
+
);
|
|
317
|
+
function toggle() {
|
|
318
|
+
this.show = !this.show;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### `<switch>` element
|
|
324
|
+
|
|
325
|
+
`<switch>` element allows you to switch the slotted content based on the `value` property. You need to define the `slot` attribute in the slotted content to match the `value`, otherwise, the default slots will be rendered.
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
function App(this: FC<{ lang: "en" | "zh" | "emoji" }>) {
|
|
329
|
+
this.lang = "en";
|
|
330
|
+
return (
|
|
331
|
+
<div>
|
|
332
|
+
<switch value={this.lang}>
|
|
333
|
+
<h1 slot="en">Hello, world!</h1>
|
|
334
|
+
<h1 slot="zh">δ½ ε₯½οΌδΈηοΌ</h1>
|
|
335
|
+
<h1>βπβοΈ</h1>
|
|
336
|
+
</switch>
|
|
337
|
+
<button onClick={() => this.lang = "en"}>English</button>
|
|
338
|
+
<button onClick={() => this.lang = "zh"}>δΈζ</button>
|
|
339
|
+
<button onClick={() => this.lang = "emoji"}>Emoji</button>
|
|
340
|
+
</div>
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Streaming Rendering
|
|
346
|
+
|
|
347
|
+
mono-jsx renders your `<html>` as a readable stream, that allows async function components are rendered asynchrously. You can set a `placeholder` attribute to show a loading state while the async component is loading.
|
|
348
|
+
|
|
349
|
+
```jsx
|
|
350
|
+
async function Sleep(ms) {
|
|
351
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
352
|
+
return <solt />;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export default {
|
|
356
|
+
fetch: (req) => (
|
|
357
|
+
<html>
|
|
358
|
+
<h1>Hello World!</h1>
|
|
359
|
+
<Sleep ms={1000} placeholder={<p>Sleeping...</p>}>
|
|
360
|
+
<p>After 1 second</p>
|
|
361
|
+
</Sleep>
|
|
362
|
+
</html>
|
|
363
|
+
),
|
|
364
|
+
};
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
You can also set `rendering` attribute to "eager" to render the async component eagerly, which means the async component will be rendered as a sync function component and the `placeholder` will be ignored.
|
|
368
|
+
|
|
369
|
+
```jsx
|
|
370
|
+
async function Sleep(ms) {
|
|
371
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
372
|
+
return <solt />;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export default {
|
|
376
|
+
fetch: (req) => (
|
|
377
|
+
<html>
|
|
378
|
+
<h1>Hello World!</h1>
|
|
379
|
+
<Sleep ms={1000} rendering="eager">
|
|
380
|
+
<p>After 1 second</p>
|
|
381
|
+
</Sleep>
|
|
382
|
+
</html>
|
|
383
|
+
),
|
|
384
|
+
};
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Accessing Request Info
|
|
388
|
+
|
|
389
|
+
You can access the request info in a function component by using the `request` property in the `this` context. And you must pass the `request` object to the root `<html>` element to make it work.
|
|
390
|
+
|
|
391
|
+
```tsx
|
|
392
|
+
function RequestInfo(this: FC) {
|
|
393
|
+
const { request } = this;
|
|
394
|
+
return (
|
|
395
|
+
<div>
|
|
396
|
+
<h1>Request Info</h1>
|
|
397
|
+
<p>{request.method}</p>
|
|
398
|
+
<p>{request.url}</p>
|
|
399
|
+
<p>{request.headers.get("user-agent")}</p>
|
|
400
|
+
</div>
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export default {
|
|
405
|
+
fetch: (req) => (
|
|
406
|
+
<html request={req}>
|
|
407
|
+
<RequestInfo />
|
|
408
|
+
</html>
|
|
409
|
+
),
|
|
410
|
+
};
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Customizing Response
|
|
414
|
+
|
|
415
|
+
You can add `status` or `headers` attribute to the `<html>` element to customize the response.
|
|
416
|
+
|
|
417
|
+
```jsx
|
|
418
|
+
export default {
|
|
419
|
+
fetch: (req) => (
|
|
420
|
+
<html
|
|
421
|
+
status={404}
|
|
422
|
+
headers={{
|
|
423
|
+
cacheControl: "public, max-age=0, must-revalidate",
|
|
424
|
+
setCookie: "name=value",
|
|
425
|
+
}}
|
|
426
|
+
>
|
|
427
|
+
<h1>Page Not Found</h1>
|
|
428
|
+
</html>
|
|
429
|
+
),
|
|
430
|
+
};
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## License
|
|
434
|
+
|
|
435
|
+
[MIT](LICENSE)
|
package/bin/mono-jsx
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
|
|
6
|
+
switch (process.argv[2]) {
|
|
7
|
+
case "setup":
|
|
8
|
+
setup().then(() => {
|
|
9
|
+
console.log("β
JSX runtime setup complete.");
|
|
10
|
+
});
|
|
11
|
+
break;
|
|
12
|
+
default:
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function setup() {
|
|
17
|
+
let tsConfigPath = globalThis.Deno ? "deno.json" : "tsconfig.json";
|
|
18
|
+
let tsConfig = Object.create(null);
|
|
19
|
+
try {
|
|
20
|
+
const json = await readFile(tsConfigPath, "utf8");
|
|
21
|
+
tsConfig = JSON.parse(json);
|
|
22
|
+
} catch {
|
|
23
|
+
// ignore
|
|
24
|
+
}
|
|
25
|
+
tsConfig.compilerOptions = {
|
|
26
|
+
...tsConfig.compilerOptions,
|
|
27
|
+
jsx: "react-jsx",
|
|
28
|
+
jsxImportSource: "mono-jsx",
|
|
29
|
+
};
|
|
30
|
+
if (!globalThis.Deno) {
|
|
31
|
+
tsConfig.compilerOptions.alllowJs = true
|
|
32
|
+
}
|
|
33
|
+
await writeFile(tsConfigPath, JSON.stringify(tsConfig, null, 2));
|
|
34
|
+
}
|
package/index.mjs
ADDED