From c74923eb30e74081780c42b02390f45c6d189fee Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins Date: Sun, 21 Jun 2026 07:53:19 +0100 Subject: [PATCH] [AI] Replace vite-plugin-peggy-loader with an in-repo Vite plugin (#8285) * [AI] Replace vite-plugin-peggy-loader with in-repo Peggy plugin Drop the third-party vite-plugin-peggy-loader dependency in favor of a small in-repo Vite plugin (packages/loot-core/scripts/peggy.mts) that compiles .pegjs grammars using the existing peggy dependency. Wire it into the loot-core and api vite/vitest configs, and remove the now-dead loader from the component-library config (it imports no grammars). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Up3H4YR7L8Qb4UKxbasyMp * [AI] Host the Peggy Vite plugin in a workspace package Move the in-repo Peggy loader out of packages/loot-core/scripts and into a dedicated private workspace package, @actual-app/vite-plugin-peggy, so the loot-core and api configs reference it as a normal workspace dependency instead of reaching across packages with ../loot-core relative imports. The peggy dependency now lives with the plugin that uses it. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Up3H4YR7L8Qb4UKxbasyMp * [AI] Rename release note to match PR number Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Up3H4YR7L8Qb4UKxbasyMp --------- Co-authored-by: Claude --- packages/api/package.json | 2 +- packages/api/vite.browser-worker.config.mts | 2 +- packages/api/vite.config.mts | 2 +- .../component-library/vitest.web.config.ts | 3 +- packages/loot-core/package.json | 3 +- .../typings/vite-plugin-peggy-loader.ts | 1 - packages/loot-core/vite.config.mts | 2 +- packages/loot-core/vite.desktop.config.mts | 2 +- packages/loot-core/vitest.config.ts | 2 +- packages/loot-core/vitest.web.config.ts | 2 +- packages/vite-plugin-peggy/index.js | 30 +++++++++++++++++++ packages/vite-plugin-peggy/package.json | 15 ++++++++++ upcoming-release-notes/8285.md | 6 ++++ yarn.lock | 24 +++++++-------- 14 files changed, 72 insertions(+), 24 deletions(-) delete mode 100644 packages/loot-core/typings/vite-plugin-peggy-loader.ts create mode 100644 packages/vite-plugin-peggy/index.js create mode 100644 packages/vite-plugin-peggy/package.json create mode 100644 upcoming-release-notes/8285.md diff --git a/packages/api/package.json b/packages/api/package.json index 0862c5a074..88145797ce 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -62,13 +62,13 @@ "uuid": "^14.0.0" }, "devDependencies": { + "@actual-app/vite-plugin-peggy": "workspace:*", "@playwright/test": "1.59.1", "@typescript/native-preview": "beta", "rollup-plugin-visualizer": "^7.0.1", "typescript-strict-plugin": "^2.4.4", "vite": "^8.0.16", "vite-plugin-node-polyfills": "^0.28.0", - "vite-plugin-peggy-loader": "^2.0.1", "vitest": "^4.1.8" }, "engines": { diff --git a/packages/api/vite.browser-worker.config.mts b/packages/api/vite.browser-worker.config.mts index 0f179bb48f..6025a828f4 100644 --- a/packages/api/vite.browser-worker.config.mts +++ b/packages/api/vite.browser-worker.config.mts @@ -1,8 +1,8 @@ import path from 'path'; +import { peggyLoader } from '@actual-app/vite-plugin-peggy'; import { defineConfig } from 'vite'; import { nodePolyfills } from 'vite-plugin-node-polyfills'; -import peggyLoader from 'vite-plugin-peggy-loader'; const distDir = path.resolve(__dirname, 'dist'); diff --git a/packages/api/vite.config.mts b/packages/api/vite.config.mts index 96ca244024..34ed68ca6e 100644 --- a/packages/api/vite.config.mts +++ b/packages/api/vite.config.mts @@ -1,9 +1,9 @@ import fs from 'fs'; import path from 'path'; +import { peggyLoader } from '@actual-app/vite-plugin-peggy'; import { visualizer } from 'rollup-plugin-visualizer'; import { defineConfig } from 'vite'; -import peggyLoader from 'vite-plugin-peggy-loader'; import { configDefaults } from 'vitest/config'; const lootCoreRoot = path.resolve(__dirname, '../loot-core'); diff --git a/packages/component-library/vitest.web.config.ts b/packages/component-library/vitest.web.config.ts index e02325ca27..cec0058299 100644 --- a/packages/component-library/vitest.web.config.ts +++ b/packages/component-library/vitest.web.config.ts @@ -1,5 +1,4 @@ import react from '@vitejs/plugin-react'; -import peggyLoader from 'vite-plugin-peggy-loader'; import { defineConfig } from 'vitest/config'; export default defineConfig({ @@ -9,5 +8,5 @@ export default defineConfig({ include: ['src/**/*.web.test.(js|jsx|ts|tsx)'], maxWorkers: 2, }, - plugins: [react(), peggyLoader()], + plugins: [react()], }); diff --git a/packages/loot-core/package.json b/packages/loot-core/package.json index d8e0506580..12677c1437 100644 --- a/packages/loot-core/package.json +++ b/packages/loot-core/package.json @@ -207,6 +207,7 @@ }, "devDependencies": { "@actual-app/crdt": "workspace:*", + "@actual-app/vite-plugin-peggy": "workspace:*", "@types/adm-zip": "^0.5.8", "@types/better-sqlite3": "^7.6.13", "@types/jlongster__sql.js": "npm:@types/sql.js@latest", @@ -224,7 +225,6 @@ "mockdate": "^3.0.5", "npm-run-all": "^4.1.5", "path-browserify": "^1.0.1", - "peggy": "5.1.0", "rollup-plugin-visualizer": "^7.0.1", "stream-browserify": "^3.0.0", "timers-browserify": "^2.0.12", @@ -233,7 +233,6 @@ "util": "^0.12.5", "vite": "^8.0.16", "vite-plugin-node-polyfills": "^0.28.0", - "vite-plugin-peggy-loader": "^2.0.1", "vitest": "^4.1.8", "yargs": "^18.0.0" } diff --git a/packages/loot-core/typings/vite-plugin-peggy-loader.ts b/packages/loot-core/typings/vite-plugin-peggy-loader.ts deleted file mode 100644 index 1513ca1afe..0000000000 --- a/packages/loot-core/typings/vite-plugin-peggy-loader.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'vite-plugin-peggy-loader'; diff --git a/packages/loot-core/vite.config.mts b/packages/loot-core/vite.config.mts index 4e32213ef1..0497795bce 100644 --- a/packages/loot-core/vite.config.mts +++ b/packages/loot-core/vite.config.mts @@ -1,9 +1,9 @@ import path from 'path'; +import { peggyLoader } from '@actual-app/vite-plugin-peggy'; import { visualizer } from 'rollup-plugin-visualizer'; import { defineConfig } from 'vite'; import { nodePolyfills } from 'vite-plugin-node-polyfills'; -import peggyLoader from 'vite-plugin-peggy-loader'; // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { diff --git a/packages/loot-core/vite.desktop.config.mts b/packages/loot-core/vite.desktop.config.mts index 23512b40cc..eba065dcaf 100644 --- a/packages/loot-core/vite.desktop.config.mts +++ b/packages/loot-core/vite.desktop.config.mts @@ -1,8 +1,8 @@ import path from 'path'; +import { peggyLoader } from '@actual-app/vite-plugin-peggy'; import { visualizer } from 'rollup-plugin-visualizer'; import { defineConfig } from 'vite'; -import peggyLoader from 'vite-plugin-peggy-loader'; export default defineConfig(({ mode }) => { const outDir = path.resolve(__dirname, 'lib-dist/electron'); diff --git a/packages/loot-core/vitest.config.ts b/packages/loot-core/vitest.config.ts index c3adc85b41..cce0b9ee10 100644 --- a/packages/loot-core/vitest.config.ts +++ b/packages/loot-core/vitest.config.ts @@ -1,4 +1,4 @@ -import peggyLoader from 'vite-plugin-peggy-loader'; +import { peggyLoader } from '@actual-app/vite-plugin-peggy'; import { defineConfig } from 'vitest/config'; export default defineConfig({ diff --git a/packages/loot-core/vitest.web.config.ts b/packages/loot-core/vitest.web.config.ts index 776f408948..909553cf51 100644 --- a/packages/loot-core/vitest.web.config.ts +++ b/packages/loot-core/vitest.web.config.ts @@ -1,4 +1,4 @@ -import peggyLoader from 'vite-plugin-peggy-loader'; +import { peggyLoader } from '@actual-app/vite-plugin-peggy'; import { defineConfig } from 'vitest/config'; export default defineConfig({ diff --git a/packages/vite-plugin-peggy/index.js b/packages/vite-plugin-peggy/index.js new file mode 100644 index 0000000000..aae173cea9 --- /dev/null +++ b/packages/vite-plugin-peggy/index.js @@ -0,0 +1,30 @@ +import peggy from 'peggy'; + +// Matches the grammar files imported across the codebase (`.pegjs`/`.peggy`). +const GRAMMAR_RE = /\.peg(js|gy)$/; + +/** + * In-repo replacement for the third-party `vite-plugin-peggy-loader`. Compiles + * imported Peggy grammars into an ES module that exports the generated parser + * (notably its `parse` function), using the `peggy` dependency directly. + * + * @returns {import('vite').Plugin} + */ +export function peggyLoader() { + return { + name: 'peggy-loader', + transform(grammar, id) { + if (!GRAMMAR_RE.test(id)) { + return null; + } + + const code = peggy.generate(grammar, { + output: 'source', + format: 'es', + grammarSource: id, + }); + + return { code, map: null }; + }, + }; +} diff --git a/packages/vite-plugin-peggy/package.json b/packages/vite-plugin-peggy/package.json new file mode 100644 index 0000000000..37abb2775a --- /dev/null +++ b/packages/vite-plugin-peggy/package.json @@ -0,0 +1,15 @@ +{ + "name": "@actual-app/vite-plugin-peggy", + "version": "0.0.0", + "private": true, + "description": "Vite plugin that compiles Peggy grammars (.pegjs) into ES modules.", + "type": "module", + "main": "./index.js", + "exports": "./index.js", + "dependencies": { + "peggy": "5.1.0" + }, + "peerDependencies": { + "vite": "*" + } +} diff --git a/upcoming-release-notes/8285.md b/upcoming-release-notes/8285.md new file mode 100644 index 0000000000..718edc3db9 --- /dev/null +++ b/upcoming-release-notes/8285.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +Replace the `vite-plugin-peggy-loader` dependency with a small in-repo Vite plugin that compiles Peggy grammars using the existing `peggy` dependency. diff --git a/yarn.lock b/yarn.lock index 9f269db493..f8cec807f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,6 +18,7 @@ __metadata: dependencies: "@actual-app/core": "workspace:*" "@actual-app/crdt": "workspace:*" + "@actual-app/vite-plugin-peggy": "workspace:*" "@playwright/test": "npm:1.59.1" "@typescript/native-preview": "npm:beta" better-sqlite3: "npm:^12.10.0" @@ -27,7 +28,6 @@ __metadata: uuid: "npm:^14.0.0" vite: "npm:^8.0.16" vite-plugin-node-polyfills: "npm:^0.28.0" - vite-plugin-peggy-loader: "npm:^2.0.1" vitest: "npm:^4.1.8" languageName: unknown linkType: soft @@ -99,6 +99,7 @@ __metadata: resolution: "@actual-app/core@workspace:packages/loot-core" dependencies: "@actual-app/crdt": "workspace:*" + "@actual-app/vite-plugin-peggy": "workspace:*" "@jlongster/sql.js": "npm:^1.6.7" "@rschedule/core": "npm:^1.5.0" "@rschedule/standard-date-adapter": "npm:^1.5.0" @@ -131,7 +132,6 @@ __metadata: mockdate: "npm:^3.0.5" npm-run-all: "npm:^4.1.5" path-browserify: "npm:^1.0.1" - peggy: "npm:5.1.0" promise-retry: "npm:^2.0.1" rollup-plugin-visualizer: "npm:^7.0.1" stream-browserify: "npm:^3.0.0" @@ -143,7 +143,6 @@ __metadata: uuid: "npm:^14.0.0" vite: "npm:^8.0.16" vite-plugin-node-polyfills: "npm:^0.28.0" - vite-plugin-peggy-loader: "npm:^2.0.1" vitest: "npm:^4.1.8" xml2js: "npm:^0.6.2" yargs: "npm:^18.0.0" @@ -209,6 +208,16 @@ __metadata: languageName: unknown linkType: soft +"@actual-app/vite-plugin-peggy@workspace:*, @actual-app/vite-plugin-peggy@workspace:packages/vite-plugin-peggy": + version: 0.0.0-use.local + resolution: "@actual-app/vite-plugin-peggy@workspace:packages/vite-plugin-peggy" + dependencies: + peggy: "npm:5.1.0" + peerDependencies: + vite: "*" + languageName: unknown + linkType: soft + "@actual-app/web@workspace:*, @actual-app/web@workspace:packages/desktop-client": version: 0.0.0-use.local resolution: "@actual-app/web@workspace:packages/desktop-client" @@ -26861,15 +26870,6 @@ __metadata: languageName: node linkType: hard -"vite-plugin-peggy-loader@npm:^2.0.1": - version: 2.0.1 - resolution: "vite-plugin-peggy-loader@npm:2.0.1" - peerDependencies: - peggy: ^1.2.0 || ^3.0.2 || ^4.0.0 - checksum: 10/55460efe15fe84774907a0f46b4351bc3d5e672c32575af3142aca27b99b64c45727e3159bfb191fdc9b890fba4a08eb306e4a8ce4823b1cfcfaa4bf79fa62ff - languageName: node - linkType: hard - "vite-plugin-pwa@npm:^1.3.0": version: 1.3.0 resolution: "vite-plugin-pwa@npm:1.3.0"