@tsrx/turbopack-plugin-react 0.1.88 → 0.1.90
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 +49 -0
- package/package.json +2 -2
- package/src/css-loader.js +1 -1
- package/src/loader.js +11 -91
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @tsrx/turbopack-plugin-react
|
|
2
|
+
|
|
3
|
+
Turbopack integration for compiling `@tsrx/react` `.tsrx` files in Next.js.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @tsrx/react react react-dom
|
|
9
|
+
pnpm add -D @tsrx/turbopack-plugin-react next
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import tsrxReactTurbopack from '@tsrx/turbopack-plugin-react';
|
|
16
|
+
|
|
17
|
+
export default tsrxReactTurbopack({
|
|
18
|
+
reactStrictMode: true,
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The helper installs Turbopack rules that compile `.tsrx` modules with
|
|
23
|
+
`@tsrx/react` and return the result as `*.tsx` so Next's React pipeline can finish
|
|
24
|
+
the JSX transform. Sibling-scoped `<style>` blocks (each styles its siblings and
|
|
25
|
+
everything below them) are emitted through a sibling `?tsrx-css&lang.css` import
|
|
26
|
+
and handed back to Turbopack as a CSS module.
|
|
27
|
+
|
|
28
|
+
It also adds `.tsrx` to `turbopack.resolveExtensions`.
|
|
29
|
+
|
|
30
|
+
## Options
|
|
31
|
+
|
|
32
|
+
Pass Next.js config as the first argument. The second argument is optional:
|
|
33
|
+
|
|
34
|
+
- `runtimeImports`: helper import mode (`'compiler'` by default, or `'direct'` for
|
|
35
|
+
standalone runtime imports).
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
export default tsrxReactTurbopack({}, { runtimeImports: 'direct' });
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
When using `runtimeImports: 'direct'`, install the runtime as a direct production
|
|
42
|
+
dependency of the package that owns the compiled modules:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm add @tsrx/react-runtime
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The helper only emits bare `@tsrx/react-runtime/*` imports and does not provide
|
|
49
|
+
the runtime package.
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Turbopack integration for @tsrx/react",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.90",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"publishConfig": {
|
|
9
9
|
"access": "public"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@tsrx/react": "0.2.
|
|
23
|
+
"@tsrx/react": "0.2.67"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"next": ">=15.3.0"
|
package/src/css-loader.js
CHANGED
|
@@ -13,7 +13,7 @@ import { compile } from '@tsrx/react';
|
|
|
13
13
|
/**
|
|
14
14
|
* Re-runs the `@tsrx/react` compiler against the `.tsrx` source to extract
|
|
15
15
|
* the scoped CSS emitted by its `<style>` block. Invoked when Turbopack
|
|
16
|
-
* resolves the sibling `?tsrx-css&lang.css` import
|
|
16
|
+
* resolves the sibling `?tsrx-css&lang.css` import emitted by the JS loader.
|
|
17
17
|
*
|
|
18
18
|
* @this {LoaderContext}
|
|
19
19
|
* @param {string} source
|
package/src/loader.js
CHANGED
|
@@ -5,97 +5,18 @@ import { compile } from '@tsrx/react';
|
|
|
5
5
|
const CSS_QUERY = '?tsrx-css&lang.css';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const char = source[index];
|
|
15
|
-
if (char === ' ' || char === '\t' || char === '\n' || char === '\r') {
|
|
16
|
-
index++;
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
if (char === '/' && source[index + 1] === '/') {
|
|
20
|
-
index += 2;
|
|
21
|
-
while (index < source.length && source[index] !== '\n') {
|
|
22
|
-
index++;
|
|
23
|
-
}
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
if (char === '/' && source[index + 1] === '*') {
|
|
27
|
-
index += 2;
|
|
28
|
-
while (index < source.length && !(source[index] === '*' && source[index + 1] === '/')) {
|
|
29
|
-
index++;
|
|
30
|
-
}
|
|
31
|
-
index = Math.min(index + 2, source.length);
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
return index;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @param {string} source
|
|
41
|
-
* @param {number} index
|
|
42
|
-
* @returns {number}
|
|
43
|
-
*/
|
|
44
|
-
function read_directive_statement(source, index) {
|
|
45
|
-
const quote = source[index];
|
|
46
|
-
if (quote !== '"' && quote !== "'") {
|
|
47
|
-
return -1;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
let cursor = index + 1;
|
|
51
|
-
let value = '';
|
|
52
|
-
while (cursor < source.length) {
|
|
53
|
-
const char = source[cursor];
|
|
54
|
-
if (char === '\\') {
|
|
55
|
-
value += source.slice(cursor, cursor + 2);
|
|
56
|
-
cursor += 2;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (char === quote) {
|
|
60
|
-
cursor++;
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
value += char;
|
|
64
|
-
cursor++;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (cursor > source.length || !value.startsWith('use ')) {
|
|
68
|
-
return -1;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
cursor = skip_whitespace_and_comments(source, cursor);
|
|
72
|
-
if (source[cursor] === ';') {
|
|
73
|
-
cursor++;
|
|
74
|
-
}
|
|
75
|
-
return skip_whitespace_and_comments(source, cursor);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
8
|
+
* Appends an import of the sibling virtual CSS resource. It goes after the
|
|
9
|
+
* module's own imports so the stylesheets of imported themes are added to the
|
|
10
|
+
* graph first and a rule in the applying module wins at equal specificity.
|
|
11
|
+
* Top-level directives such as `'use client'` stay first, and nothing above
|
|
12
|
+
* the import moves, so the compiler's source map still applies.
|
|
13
|
+
*
|
|
79
14
|
* @param {string} code
|
|
80
15
|
* @param {string} resource_path
|
|
81
16
|
* @returns {string}
|
|
82
17
|
*/
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
const initial_index = skip_whitespace_and_comments(code, 0);
|
|
86
|
-
let insertion_index = initial_index;
|
|
87
|
-
let scan_index = initial_index;
|
|
88
|
-
|
|
89
|
-
while (scan_index < code.length) {
|
|
90
|
-
const next_index = read_directive_statement(code, scan_index);
|
|
91
|
-
if (next_index === -1) {
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
insertion_index = next_index;
|
|
95
|
-
scan_index = next_index;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return `${code.slice(0, insertion_index)}${css_import}${code.slice(insertion_index)}`;
|
|
18
|
+
function append_css_import(code, resource_path) {
|
|
19
|
+
return `${code}\nimport ${JSON.stringify(resource_path + CSS_QUERY)};\n`;
|
|
99
20
|
}
|
|
100
21
|
|
|
101
22
|
/**
|
|
@@ -109,7 +30,7 @@ function prepend_css_import(code, resource_path) {
|
|
|
109
30
|
/**
|
|
110
31
|
* Compile `.tsrx` files to TSX for consumption by Turbopack's built-in
|
|
111
32
|
* TypeScript/React pipeline. When a component-local `<style>` block is
|
|
112
|
-
* present,
|
|
33
|
+
* present, append an import of a sibling virtual CSS resource that is handled
|
|
113
34
|
* by the Turbopack config helper's query-targeted CSS rule.
|
|
114
35
|
*
|
|
115
36
|
* @this {LoaderContext}
|
|
@@ -121,10 +42,9 @@ export default function tsrx_react_turbopack_loader(source) {
|
|
|
121
42
|
|
|
122
43
|
try {
|
|
123
44
|
const { code, map, css } = compile(source, this.resourcePath, this.getOptions?.());
|
|
124
|
-
const output = css ?
|
|
125
|
-
const output_map = css ? null : map;
|
|
45
|
+
const output = css ? append_css_import(code, this.resourcePath) : code;
|
|
126
46
|
|
|
127
|
-
callback(null, output, /** @type {any} */ (
|
|
47
|
+
callback(null, output, /** @type {any} */ (map ?? undefined));
|
|
128
48
|
} catch (/** @type {any} */ err) {
|
|
129
49
|
callback(err);
|
|
130
50
|
}
|