diff --git a/apps/remix/rolldown.config.mjs b/apps/remix/rolldown.config.mjs index f3f9054f9..45b69c508 100644 --- a/apps/remix/rolldown.config.mjs +++ b/apps/remix/rolldown.config.mjs @@ -1,9 +1,6 @@ -import { transformAsync } from '@babel/core'; -import linguiMacroPlugin from '@lingui/babel-plugin-lingui-macro'; +import babel from '@rolldown/plugin-babel'; import { defineConfig } from 'rolldown'; -const linguiMacroRE = /@lingui\/(core\/macro|react\/macro|macro)/; - /** * Rolldown config for building the Hono server entry. * @@ -30,28 +27,11 @@ export default defineConfig({ tsconfigFilename: 'tsconfig.json', }, plugins: [ - { - name: 'lingui-macro', - async transform(code, id) { - if (!/\.(tsx?|jsx?)$/.test(id)) return; - if (!linguiMacroRE.test(code)) return; - - const result = await transformAsync(code, { - babelrc: false, - configFile: false, - filename: id, - parserOpts: { - sourceType: 'module', - allowAwaitOutsideFunction: true, - plugins: ['typescript', 'jsx'], - }, - plugins: [linguiMacroPlugin], - sourceMaps: true, - }); - - if (!result?.code) return; - return { code: result.code, map: result.map }; + babel({ + plugins: ['@lingui/babel-plugin-lingui-macro'], + parserOpts: { + plugins: ['typescript', 'jsx'], }, - }, + }), ], }); diff --git a/apps/remix/vite.config.ts b/apps/remix/vite.config.ts index 8c1552dd9..b7422a532 100644 --- a/apps/remix/vite.config.ts +++ b/apps/remix/vite.config.ts @@ -1,14 +1,12 @@ -import { transformAsync } from '@babel/core'; -import linguiMacroPlugin from '@lingui/babel-plugin-lingui-macro'; import { lingui } from '@lingui/vite-plugin'; import { reactRouter } from '@react-router/dev/vite'; +import babel from '@rolldown/plugin-babel'; import autoprefixer from 'autoprefixer'; import serverAdapter from 'hono-react-router-adapter/vite'; import { createRequire } from 'node:module'; import path from 'node:path'; import tailwindcss from 'tailwindcss'; import { defineConfig, normalizePath } from 'vite'; -import type { Plugin } from 'vite'; import { viteStaticCopy } from 'vite-plugin-static-copy'; const require = createRequire(import.meta.url); @@ -16,51 +14,6 @@ const require = createRequire(import.meta.url); const pdfjsDistPath = path.dirname(require.resolve('pdfjs-dist/package.json')); const cMapsDir = normalizePath(path.join(pdfjsDistPath, 'cmaps')); -/** - * Targeted Lingui macro compilation plugin. - * - * Replaces the generic `vite-plugin-babel-macros` which ran a full Babel - * parse + transform on every single .ts/.tsx file. This plugin: - * - * 1. Skips files that don't contain lingui macro imports (fast string check). - * 2. Uses `@lingui/babel-plugin-lingui-macro` directly instead of going - * through the generic `babel-plugin-macros` wrapper. - */ -const linguiMacroRE = /@lingui\/(core\/macro|react\/macro|macro)/; - -function linguiMacro(): Plugin { - return { - name: 'vite-plugin-lingui-macro', - enforce: 'pre', - async transform(code, id) { - if (id.includes('/node_modules/')) return; - - const [filepath] = id.split('?'); - if (!/\.(tsx?|jsx?)$/.test(filepath)) return; - - // Fast bail-out: skip files that don't reference lingui macros. - if (!linguiMacroRE.test(code)) return; - - const result = await transformAsync(code, { - babelrc: false, - configFile: false, - filename: id, - sourceFileName: filepath, - parserOpts: { - sourceType: 'module', - allowAwaitOutsideFunction: true, - plugins: ['typescript', 'jsx'], - }, - plugins: [linguiMacroPlugin], - sourceMaps: true, - }); - - if (!result?.code) return; - return { code: result.code, map: result.map }; - }, - }; -} - /** * Note: We load the env variables externally so we can have runtime enviroment variables * for docker. @@ -86,13 +39,18 @@ export default defineConfig({ }, ], }), + babel({ + plugins: ['@lingui/babel-plugin-lingui-macro'], + // @rolldown/plugin-babel's built-in TypeScript parser overrides use + // `test: "**/*.tsx"` globs which fail to match when React Router appends + // query strings (e.g. `?__react-router-build-client-route`) to module IDs. + // Specify parser plugins explicitly so they apply unconditionally. + parserOpts: { + plugins: ['typescript', 'jsx'], + }, + }), + lingui(), reactRouter(), - linguiMacro(), - // lingui() returns two plugins: a macro error reporter and the .po catalog - // compiler. The error reporter adds a resolveId hook on every module to - // detect uncompiled macros — redundant since linguiMacro() already compiles - // them, and it was consuming 51% of plugin time in the build. - ...lingui().filter((p) => 'name' in p && p.name !== 'vite-plugin-lingui-report-macro-error'), serverAdapter({ entry: 'server/router.ts', }), @@ -111,10 +69,6 @@ export default defineConfig({ ], }, optimizeDeps: { - // Only scan the app directory — workspace packages (ui, lib) are - // discovered transitively through app imports. The previous config - // scanned ~1,000 files including server-only code from packages/lib. - entries: ['./app/**/*'], include: ['prop-types', 'file-selector', 'attr-accept'], exclude: [ '@napi-rs/canvas', diff --git a/package-lock.json b/package-lock.json index 366c5a137..ed3358e8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "@datadog/pprof": "^5.13.5", "@lingui/cli": "^5.6.0", "@prisma/client": "^6.19.0", + "@rolldown/plugin-babel": "^0.2.0", "@trpc/client": "11.8.1", "@trpc/react-query": "11.8.1", "@trpc/server": "11.8.1", @@ -15111,6 +15112,37 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/@rolldown/plugin-babel": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@rolldown/plugin-babel/-/plugin-babel-0.2.0.tgz", + "integrity": "sha512-ZkajPtfcBTfLSZTmm40k2E0cwT5HDosBcj71fdUURXl7FfETb50jEbV39ujPw2RFp3ZpOugK3ATdX+HuFfWr9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=22.12.0 || ^24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.29.0 || ^8.0.0-rc.1", + "@babel/plugin-transform-runtime": "^7.29.0 || ^8.0.0-rc.1", + "@babel/runtime": "^7.27.0 || ^8.0.0-rc.1", + "rolldown": "^1.0.0-rc.5", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@babel/plugin-transform-runtime": { + "optional": true + }, + "@babel/runtime": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.9", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.9.tgz", diff --git a/package.json b/package.json index 1381458f9..314835480 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@datadog/pprof": "^5.13.5", "@lingui/cli": "^5.6.0", "@prisma/client": "^6.19.0", + "@rolldown/plugin-babel": "^0.2.0", "@trpc/client": "11.8.1", "@trpc/react-query": "11.8.1", "@trpc/server": "11.8.1", @@ -111,4 +112,4 @@ "zod": "^4.3.5" } } -} +} \ No newline at end of file