diff --git a/apps/renderer/vitest.config.ts b/apps/renderer/vitest.config.ts index 76c64051b..4f30ef8b7 100644 --- a/apps/renderer/vitest.config.ts +++ b/apps/renderer/vitest.config.ts @@ -5,7 +5,7 @@ import { fileURLToPath } from "node:url" import tsconfigPath from "vite-tsconfig-paths" import { defineProject } from "vitest/config" -import { twMacro } from "../../plugins/vite/tw-macro" +import { astPlugin } from "../../configs/plugins" const pkg = JSON.parse(readFileSync("package.json", "utf8")) const __dirname = fileURLToPath(new URL(".", import.meta.url)) @@ -31,11 +31,9 @@ export default defineProject({ }, plugins: [ - twMacro(), + astPlugin, tsconfigPath({ projects: ["./tsconfig.json"], }), - - twMacro(), ], }) diff --git a/apps/server/vite.config.mts b/apps/server/vite.config.mts index cc27b987e..e40fc8834 100644 --- a/apps/server/vite.config.mts +++ b/apps/server/vite.config.mts @@ -3,8 +3,8 @@ import { resolve } from "node:path" import react from "@vitejs/plugin-react" import { defineConfig } from "vite" +import { astPlugin } from "../../configs/plugins" import { viteRenderBaseConfig } from "../../configs/vite.render.config" -import { twMacro } from "../../plugins/vite/tw-macro" export default () => { return defineConfig({ @@ -27,7 +27,7 @@ export default () => { }, }, }, - plugins: [react(), twMacro()], + plugins: [react(), astPlugin], server: { proxy: { diff --git a/configs/plugins.ts b/configs/plugins.ts new file mode 100644 index 000000000..33b7f4c1a --- /dev/null +++ b/configs/plugins.ts @@ -0,0 +1,6 @@ +import { RemoveWrapperFunction } from "unplugin-ast/transformers" +import AST from "unplugin-ast/vite" + +export const astPlugin = AST({ + transformer: [RemoveWrapperFunction(["tw", "defineSettingPageData"])], +}) diff --git a/configs/vite.render.config.ts b/configs/vite.render.config.ts index 9937183e0..7c9e18c54 100644 --- a/configs/vite.render.config.ts +++ b/configs/vite.render.config.ts @@ -10,9 +10,9 @@ import type { UserConfig } from "vite" import { circularImportRefreshPlugin } from "../plugins/vite/hmr" import { customI18nHmrPlugin } from "../plugins/vite/i18n-hmr" import { localesPlugin } from "../plugins/vite/locales" -import { twMacro } from "../plugins/vite/tw-macro" import i18nCompleteness from "../plugins/vite/utils/i18n-completeness" import { getGitHash } from "../scripts/lib" +import { astPlugin } from "./plugins" const pkgDir = resolve(dirname(fileURLToPath(import.meta.url)), "..") const pkg = JSON.parse(readFileSync(resolve(pkgDir, "./package.json"), "utf8")) @@ -68,7 +68,7 @@ export const viteRenderBaseConfig = { }), localesPlugin(), - twMacro(), + astPlugin, customI18nHmrPlugin(), ], define: { diff --git a/package.json b/package.json index b719a5869..e37b9b7db 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "tsx": "4.19.2", "turbo": "2.2.3", "typescript": "5.6.3", + "unplugin-ast": "^0.11.0", "vite": "^5.4.10", "vite-plugin-mkcert": "1.17.6", "vite-tsconfig-paths": "5.0.1", diff --git a/plugins/vite/tw-macro.ts b/plugins/vite/tw-macro.ts deleted file mode 100644 index 5207e0981..000000000 --- a/plugins/vite/tw-macro.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as babel from "@babel/core" -import generate from "@babel/generator" -import { parse } from "@babel/parser" -import * as t from "@babel/types" -import type { Plugin } from "vite" - -export function twMacro(): Plugin { - return { - name: "vite-plugin-tw-to-raw-string", - - transform(code, id) { - // Only Process .tsx .ts .jsx .js files - if (!/\.[jt]sx?$/.test(id)) { - return null - } - // Parse the code using Babel's parser with TypeScript support - const ast = parse(code, { - sourceType: "module", - plugins: ["jsx", "typescript"], // Add typescript support - }) - - babel.traverse(ast, { - TaggedTemplateExpression(path) { - if (t.isIdentifier(path.node.tag, { name: "tw" })) { - const { quasi } = path.node - if (t.isTemplateLiteral(quasi)) { - // Create a new template literal by combining quasis and expressions - const quasis = quasi.quasis.map((q) => q.value.raw) - - // Replace the tagged template expression with the new template literal as a string - path.replaceWith( - t.templateLiteral( - quasis.map((q, i) => - t.templateElement({ raw: q, cooked: q }, i === quasis.length - 1), - ), - quasi.expressions, - ), - ) - } - } - }, - }) - - // Generate the transformed code from the modified AST - // @ts-expect-error - const output = generate.default(ast, {}, code) - - return { - code: output.code, - map: null, // Source map generation can be added if necessary - } - }, - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab1bc4c5f..2dd45aa80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -221,6 +221,9 @@ importers: typescript: specifier: 5.6.3 version: 5.6.3 + unplugin-ast: + specifier: ^0.11.0 + version: 0.11.0(rollup@4.24.0)(webpack-sources@3.2.3) vite: specifier: ^5.4.10 version: 5.4.10(@types/node@22.8.7)(lightningcss@1.27.0)(terser@5.35.0) @@ -3972,6 +3975,15 @@ packages: resolution: {integrity: sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==} engines: {node: '>= 10'} + '@rollup/pluginutils@5.1.3': + resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.24.0': resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} cpu: [arm] @@ -4786,6 +4798,10 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-kit@1.3.1: + resolution: {integrity: sha512-3bIRV4s/cNAee2rKjuvYdoG+0CMqtOIgCvWrJL6zG8R0fDyMwYzStspX5JqXPbdMzM+qxHZ6g2rMHKhr3HkPlQ==} + engines: {node: '>=16.14.0'} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -6213,6 +6229,9 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -7502,6 +7521,10 @@ packages: resolution: {integrity: sha512-zIUs3+qpml+w3wiRuADutd7XIO8UABqksot10Utl/tji4UxZzLG4fWDC+yJZoO8/Ehg5RqsvSRE/6TS5AEOeWw==} os: [darwin] + magic-string-ast@0.6.2: + resolution: {integrity: sha512-oN3Bcd7ZVt+0VGEs7402qR/tjgjbM7kPlH/z7ufJnzTLVBzXJITRHOJiwMmmYMgZfdoWQsfQcY+iKlxiBppnMA==} + engines: {node: '>=16.14.0'} + magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} @@ -9856,9 +9879,22 @@ packages: resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} engines: {node: '>= 0.4.0'} + unplugin-ast@0.11.0: + resolution: {integrity: sha512-faP/JmvaH0huDgfAS9QNShIyo2C9lICSNc6qQ13r7U84PUl7aVyw5RK0/E63FnazxxjFSt6QfKeonMpwu1d75A==} + engines: {node: '>=18.12.0'} + unplugin@1.0.1: resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==} + unplugin@1.15.0: + resolution: {integrity: sha512-jTPIs63W+DUEDW207ztbaoO7cQ4p5aVaB823LSlxpsFEU3Mykwxf3ZGC/wzxFJeZlASZYgVrWeo7LgOrqJZ8RA==} + engines: {node: '>=14.0.0'} + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + unused-filename@4.0.1: resolution: {integrity: sha512-ZX6U1J04K1FoSUeoX1OicAhw4d0aro2qo+L8RhJkiGTNtBNkd/Fi1Wxoc9HzcVu6HfOzm0si/N15JjxFmD1z6A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -10069,6 +10105,9 @@ packages: webpack-virtual-modules@0.5.0: resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + websocket-driver@0.7.4: resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} engines: {node: '>=0.8.0'} @@ -11119,13 +11158,13 @@ snapshots: '@babel/template@7.25.0': dependencies: '@babel/code-frame': 7.24.7 - '@babel/parser': 7.25.8 + '@babel/parser': 7.26.2 '@babel/types': 7.25.8 '@babel/template@7.25.7': dependencies: '@babel/code-frame': 7.25.7 - '@babel/parser': 7.25.8 + '@babel/parser': 7.26.2 '@babel/types': 7.25.8 '@babel/template@7.25.9': @@ -11138,7 +11177,7 @@ snapshots: dependencies: '@babel/code-frame': 7.24.7 '@babel/generator': 7.26.2 - '@babel/parser': 7.25.8 + '@babel/parser': 7.26.2 '@babel/template': 7.25.0 '@babel/types': 7.25.8 debug: 4.3.7 @@ -11150,7 +11189,7 @@ snapshots: dependencies: '@babel/code-frame': 7.25.7 '@babel/generator': 7.26.2 - '@babel/parser': 7.25.8 + '@babel/parser': 7.26.2 '@babel/template': 7.25.7 '@babel/types': 7.25.8 debug: 4.3.7 @@ -13839,6 +13878,14 @@ snapshots: '@resvg/resvg-js-win32-ia32-msvc': 2.6.2 '@resvg/resvg-js-win32-x64-msvc': 2.6.2 + '@rollup/pluginutils@5.1.3(rollup@4.24.0)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.24.0 + '@rollup/rollup-android-arm-eabi@4.24.0': optional: true @@ -14275,7 +14322,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.25.8 + '@babel/parser': 7.26.2 '@babel/types': 7.25.8 '@types/babel__traverse@7.20.6': @@ -14900,6 +14947,11 @@ snapshots: assertion-error@2.0.1: {} + ast-kit@1.3.1: + dependencies: + '@babel/parser': 7.26.2 + pathe: 1.1.2 + astral-regex@2.0.0: optional: true @@ -16688,6 +16740,8 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.6 @@ -18190,6 +18244,10 @@ snapshots: nan: 2.20.0 optional: true + magic-string-ast@0.6.2: + dependencies: + magic-string: 0.30.12 + magic-string@0.30.11: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -18772,7 +18830,7 @@ snapshots: mlly@1.7.2: dependencies: - acorn: 8.12.1 + acorn: 8.14.0 pathe: 1.1.2 pkg-types: 1.2.1 ufo: 1.5.4 @@ -20874,6 +20932,18 @@ snapshots: unorm@1.6.0: optional: true + unplugin-ast@0.11.0(rollup@4.24.0)(webpack-sources@3.2.3): + dependencies: + '@antfu/utils': 0.7.10 + '@babel/generator': 7.26.2 + '@rollup/pluginutils': 5.1.3(rollup@4.24.0) + ast-kit: 1.3.1 + magic-string-ast: 0.6.2 + unplugin: 1.15.0(webpack-sources@3.2.3) + transitivePeerDependencies: + - rollup + - webpack-sources + unplugin@1.0.1: dependencies: acorn: 8.14.0 @@ -20881,6 +20951,13 @@ snapshots: webpack-sources: 3.2.3 webpack-virtual-modules: 0.5.0 + unplugin@1.15.0(webpack-sources@3.2.3): + dependencies: + acorn: 8.14.0 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + webpack-sources: 3.2.3 + unused-filename@4.0.1: dependencies: escape-string-regexp: 5.0.0 @@ -21097,6 +21174,8 @@ snapshots: webpack-virtual-modules@0.5.0: {} + webpack-virtual-modules@0.6.2: {} + websocket-driver@0.7.4: dependencies: http-parser-js: 0.5.8