@acusti/vite-plugin-react-compiler 0.1.0 → 0.3.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/README.md CHANGED
@@ -87,8 +87,8 @@ The plugin takes an optional options object with four properties:
87
87
  [`createFilter`](https://vite.dev/guide/api-plugin#filtering-include-exclude-pattern)
88
88
  patterns selecting which modules get the compiler pass. Defaults:
89
89
  `include: /\.[jt]sx?$/`, `exclude: /[/\\]node_modules[/\\]/`.
90
- - **`reactCompiler`**: options passed verbatim to React Compiler, using the
91
- same names as [babel-plugin-react-compiler][compiler options]:
90
+ - **`compiler`**: options passed verbatim to React Compiler, using the same
91
+ names as [babel-plugin-react-compiler][compiler options]:
92
92
  `compilationMode`, `panicThreshold` (defaults to `'none'`), `target`
93
93
  (defaults to `'19'`), `environment` flags like
94
94
  `enableTreatRefLikeIdentifiersAsRefs`, and so on. Callback-valued options
@@ -104,7 +104,7 @@ The plugin takes an optional options object with four properties:
104
104
  ```ts
105
105
  reactCompiler({
106
106
  exclude: [/node_modules/, /\.stories\./],
107
- reactCompiler: {
107
+ compiler: {
108
108
  environment: { enableTreatRefLikeIdentifiersAsRefs: true },
109
109
  },
110
110
  });
package/dist/index.d.ts CHANGED
@@ -24,6 +24,6 @@ export type Options = {
24
24
  * babel-plugin-react-compiler (compilationMode, panicThreshold
25
25
  * (defaults to 'none'), target (defaults to '19'), environment, etc.).
26
26
  */
27
- reactCompiler?: ReactCompilerOptions;
27
+ compiler?: ReactCompilerOptions;
28
28
  };
29
29
  export default function vitePluginReactCompiler(options?: Options): Plugin;
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ function vitePluginReactCompiler(options = {}) {
18
18
  const run = async () => {
19
19
  const transformed = await transform(filepath, code, {
20
20
  jsx: "preserve",
21
- reactCompiler: options.reactCompiler ?? {},
21
+ reactCompiler: options.compiler ?? {},
22
22
  sourcemap: true
23
23
  });
24
24
  if (transformed.fatal) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport { createHash } from 'node:crypto';\n\nimport {\n type ReactCompilerOptions,\n type SourceMap,\n transform,\n} from 'oxc-transform-react';\nimport { createFilter, type FilterPattern, type Plugin } from 'vite';\n\nexport type Options = {\n /**\n * Modules to exclude from the compiler pass (takes precedence over\n * include).\n * @default /[/\\\\]node_modules[/\\\\]/\n */\n exclude?: FilterPattern;\n /**\n * Modules to run the compiler pass on.\n * @default /\\.[jt]sx?$/\n */\n include?: FilterPattern;\n /**\n * Cache transform results by module id + content hash so repeated\n * transforms of identical content (e.g. one per environment in\n * multi-environment builds) only run the compiler once per file.\n * @default true\n */\n memoize?: boolean;\n /**\n * Options passed verbatim to React Compiler, using the same names as\n * babel-plugin-react-compiler (compilationMode, panicThreshold\n * (defaults to 'none'), target (defaults to '19'), environment, etc.).\n */\n reactCompiler?: ReactCompilerOptions;\n};\n\ntype CachedTransform = {\n hash: string;\n result: Promise<TransformOutput>;\n};\n\ntype TransformOutput = { code: string; map?: SourceMap };\n\nconst defaultExclude = /[/\\\\]node_modules[/\\\\]/;\nconst defaultInclude = /\\.[jt]sx?$/;\n\nexport default function vitePluginReactCompiler(options: Options = {}): Plugin {\n const filter = createFilter(\n options.include ?? defaultInclude,\n options.exclude ?? defaultExclude,\n );\n const isMemoizing = options.memoize !== false;\n // one entry per module id, replaced whenever the content hash changes;\n // holds the promise so overlapping transforms of identical content\n // (e.g. concurrent client + SSR environments) share a single run\n const cache = new Map<string, CachedTransform>();\n\n return {\n enforce: 'pre',\n name: 'vite-plugin-react-compiler',\n transform(code, id) {\n // vite module ids can carry a query suffix (e.g. sub-request\n // queries from other plugins); filter, cache, and compile by\n // the underlying file path — like @vitejs/plugin-react — so\n // the cache stays one-entry-per-file and sourcemap sources\n // don’t include vite queries\n const [filepath] = id.split('?');\n if (!filter(filepath)) return null;\n\n const run = async (): Promise<TransformOutput> => {\n const transformed = await transform(filepath, code, {\n // leave JSX for vite’s own pipeline (refresh, dev runtime)\n jsx: 'preserve',\n reactCompiler: options.reactCompiler ?? {},\n sourcemap: true,\n });\n\n // fatal means a parse failure or rejected options: no code\n // was emitted, so break the build like a Babel syntax error\n // would, forwarding the first error’s position so vite can\n // report the location alongside oxc’s own code frames\n if (transformed.fatal) {\n // oxc label offsets are utf-8 byte offsets, but rollup’s\n // pos argument indexes the (utf-16) code string\n const byteStart = transformed.errors[0]?.labels[0]?.start;\n this.error(\n transformed.errors\n .map((error) =>\n error.codeframe\n ? `${error.message}\\n${error.codeframe}`\n : error.message,\n )\n .join('\\n'),\n byteStart == null\n ? undefined\n : Buffer.from(code, 'utf8')\n .subarray(0, byteStart)\n .toString('utf8').length,\n );\n }\n\n return { code: transformed.code, map: transformed.map };\n };\n\n if (!isMemoizing) return run();\n\n const hash = createHash('sha1').update(code).digest('hex');\n const cached = cache.get(filepath);\n if (cached?.hash === hash) return cached.result;\n\n const result = run();\n cache.set(filepath, { hash, result });\n // drop failed transforms so the next request retries them\n result.catch(() => {\n if (cache.get(filepath)?.result === result) cache.delete(filepath);\n });\n return result;\n },\n };\n}\n"],"mappings":";;;;;AA4CA,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AAEvB,SAAwB,wBAAwB,UAAmB,CAAC,GAAW;CAC3E,MAAM,SAAS,aACX,QAAQ,WAAW,gBACnB,QAAQ,WAAW,cACvB;CACA,MAAM,cAAc,QAAQ,YAAY;CAIxC,MAAM,wBAAQ,IAAI,IAA6B;CAE/C,OAAO;EACH,SAAS;EACT,MAAM;EACN,UAAU,MAAM,IAAI;GAMhB,MAAM,CAAC,YAAY,GAAG,MAAM,GAAG;GAC/B,IAAI,CAAC,OAAO,QAAQ,GAAG,OAAO;GAE9B,MAAM,MAAM,YAAsC;IAC9C,MAAM,cAAc,MAAM,UAAU,UAAU,MAAM;KAEhD,KAAK;KACL,eAAe,QAAQ,iBAAiB,CAAC;KACzC,WAAW;IACf,CAAC;IAMD,IAAI,YAAY,OAAO;KAGnB,MAAM,YAAY,YAAY,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE;KACpD,KAAK,MACD,YAAY,OACP,KAAK,UACF,MAAM,YACA,GAAG,MAAM,QAAQ,IAAI,MAAM,cAC3B,MAAM,OAChB,CAAC,CACA,KAAK,IAAI,GACd,aAAa,OACP,KAAA,IACA,OAAO,KAAK,MAAM,MAAM,CAAC,CACpB,SAAS,GAAG,SAAS,CAAC,CACtB,SAAS,MAAM,CAAC,CAAC,MAChC;IACJ;IAEA,OAAO;KAAE,MAAM,YAAY;KAAM,KAAK,YAAY;IAAI;GAC1D;GAEA,IAAI,CAAC,aAAa,OAAO,IAAI;GAE7B,MAAM,OAAO,WAAW,MAAM,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK;GACzD,MAAM,SAAS,MAAM,IAAI,QAAQ;GACjC,IAAI,QAAQ,SAAS,MAAM,OAAO,OAAO;GAEzC,MAAM,SAAS,IAAI;GACnB,MAAM,IAAI,UAAU;IAAE;IAAM;GAAO,CAAC;GAEpC,OAAO,YAAY;IACf,IAAI,MAAM,IAAI,QAAQ,CAAC,EAAE,WAAW,QAAQ,MAAM,OAAO,QAAQ;GACrE,CAAC;GACD,OAAO;EACX;CACJ;AACJ"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport { createHash } from 'node:crypto';\n\nimport {\n type ReactCompilerOptions,\n type SourceMap,\n transform,\n} from 'oxc-transform-react';\nimport { createFilter, type FilterPattern, type Plugin } from 'vite';\n\nexport type Options = {\n /**\n * Modules to exclude from the compiler pass (takes precedence over\n * include).\n * @default /[/\\\\]node_modules[/\\\\]/\n */\n exclude?: FilterPattern;\n /**\n * Modules to run the compiler pass on.\n * @default /\\.[jt]sx?$/\n */\n include?: FilterPattern;\n /**\n * Cache transform results by module id + content hash so repeated\n * transforms of identical content (e.g. one per environment in\n * multi-environment builds) only run the compiler once per file.\n * @default true\n */\n memoize?: boolean;\n /**\n * Options passed verbatim to React Compiler, using the same names as\n * babel-plugin-react-compiler (compilationMode, panicThreshold\n * (defaults to 'none'), target (defaults to '19'), environment, etc.).\n */\n compiler?: ReactCompilerOptions;\n};\n\ntype CachedTransform = {\n hash: string;\n result: Promise<TransformOutput>;\n};\n\ntype TransformOutput = { code: string; map?: SourceMap };\n\nconst defaultExclude = /[/\\\\]node_modules[/\\\\]/;\nconst defaultInclude = /\\.[jt]sx?$/;\n\nexport default function vitePluginReactCompiler(options: Options = {}): Plugin {\n const filter = createFilter(\n options.include ?? defaultInclude,\n options.exclude ?? defaultExclude,\n );\n const isMemoizing = options.memoize !== false;\n // one entry per module id, replaced whenever the content hash changes;\n // holds the promise so overlapping transforms of identical content\n // (e.g. concurrent client + SSR environments) share a single run\n const cache = new Map<string, CachedTransform>();\n\n return {\n enforce: 'pre',\n name: 'vite-plugin-react-compiler',\n transform(code, id) {\n // vite module ids can carry a query suffix (e.g. sub-request\n // queries from other plugins); filter, cache, and compile by\n // the underlying file path — like @vitejs/plugin-react — so\n // the cache stays one-entry-per-file and sourcemap sources\n // don’t include vite queries\n const [filepath] = id.split('?');\n if (!filter(filepath)) return null;\n\n const run = async (): Promise<TransformOutput> => {\n const transformed = await transform(filepath, code, {\n // leave JSX for vite’s own pipeline (refresh, dev runtime)\n jsx: 'preserve',\n reactCompiler: options.compiler ?? {},\n sourcemap: true,\n });\n\n // fatal means a parse failure or rejected options: no code\n // was emitted, so break the build like a Babel syntax error\n // would, forwarding the first error’s position so vite can\n // report the location alongside oxc’s own code frames\n if (transformed.fatal) {\n // oxc label offsets are utf-8 byte offsets, but rollup’s\n // pos argument indexes the (utf-16) code string\n const byteStart = transformed.errors[0]?.labels[0]?.start;\n this.error(\n transformed.errors\n .map((error) =>\n error.codeframe\n ? `${error.message}\\n${error.codeframe}`\n : error.message,\n )\n .join('\\n'),\n byteStart == null\n ? undefined\n : Buffer.from(code, 'utf8')\n .subarray(0, byteStart)\n .toString('utf8').length,\n );\n }\n\n return { code: transformed.code, map: transformed.map };\n };\n\n if (!isMemoizing) return run();\n\n const hash = createHash('sha1').update(code).digest('hex');\n const cached = cache.get(filepath);\n if (cached?.hash === hash) return cached.result;\n\n const result = run();\n cache.set(filepath, { hash, result });\n // drop failed transforms so the next request retries them\n result.catch(() => {\n if (cache.get(filepath)?.result === result) cache.delete(filepath);\n });\n return result;\n },\n };\n}\n"],"mappings":";;;;;AA4CA,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AAEvB,SAAwB,wBAAwB,UAAmB,CAAC,GAAW;CAC3E,MAAM,SAAS,aACX,QAAQ,WAAW,gBACnB,QAAQ,WAAW,cACvB;CACA,MAAM,cAAc,QAAQ,YAAY;CAIxC,MAAM,wBAAQ,IAAI,IAA6B;CAE/C,OAAO;EACH,SAAS;EACT,MAAM;EACN,UAAU,MAAM,IAAI;GAMhB,MAAM,CAAC,YAAY,GAAG,MAAM,GAAG;GAC/B,IAAI,CAAC,OAAO,QAAQ,GAAG,OAAO;GAE9B,MAAM,MAAM,YAAsC;IAC9C,MAAM,cAAc,MAAM,UAAU,UAAU,MAAM;KAEhD,KAAK;KACL,eAAe,QAAQ,YAAY,CAAC;KACpC,WAAW;IACf,CAAC;IAMD,IAAI,YAAY,OAAO;KAGnB,MAAM,YAAY,YAAY,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE;KACpD,KAAK,MACD,YAAY,OACP,KAAK,UACF,MAAM,YACA,GAAG,MAAM,QAAQ,IAAI,MAAM,cAC3B,MAAM,OAChB,CAAC,CACA,KAAK,IAAI,GACd,aAAa,OACP,KAAA,IACA,OAAO,KAAK,MAAM,MAAM,CAAC,CACpB,SAAS,GAAG,SAAS,CAAC,CACtB,SAAS,MAAM,CAAC,CAAC,MAChC;IACJ;IAEA,OAAO;KAAE,MAAM,YAAY;KAAM,KAAK,YAAY;IAAI;GAC1D;GAEA,IAAI,CAAC,aAAa,OAAO,IAAI;GAE7B,MAAM,OAAO,WAAW,MAAM,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK;GACzD,MAAM,SAAS,MAAM,IAAI,QAAQ;GACjC,IAAI,QAAQ,SAAS,MAAM,OAAO,OAAO;GAEzC,MAAM,SAAS,IAAI;GACnB,MAAM,IAAI,UAAU;IAAE;IAAM;GAAO,CAAC;GAEpC,OAAO,YAAY;IACf,IAAI,MAAM,IAAI,QAAQ,CAAC,EAAE,WAAW,QAAQ,MAAM,OAAO,QAAQ;GACrE,CAAC;GACD,OAAO;EACX;CACJ;AACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acusti/vite-plugin-react-compiler",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Vite plugin that runs React Compiler via oxc-transform-react, the native Rust port’s Node bindings, instead of Babel",
5
5
  "keywords": [
6
6
  "memoization",
@@ -41,7 +41,7 @@
41
41
  "tsc": "tsc --noEmit"
42
42
  },
43
43
  "dependencies": {
44
- "oxc-transform-react": "0.144.0"
44
+ "oxc-transform-react": "0.145.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/node": "^26.1.0",