From 30c20708be29b9d77ac83efa409a6563e0d910ef Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 4 Mar 2026 01:48:27 -0500 Subject: [PATCH] fix: exclude devtools code from production builds (#4972) Three changes to prevent Vue Devtools integration from leaking into production bundles: 1. Wrap module-level variable initializations in __DEV__ guard so they are eliminated as dead code in production builds. 2. Make refreshInspector a no-op in production by wrapping the throttle() call in a __DEV__ ternary, removing the module-level side effect that prevented tree-shaking. 3. Add /* @vite-ignore */ to the dynamic import('@vue/devtools-api') to prevent Vite from creating a separate chunk for it in library mode builds. Co-Authored-By: Claude Opus 4.6 --- .changeset/fix-4972-devtools-production.md | 5 ++ packages/vee-validate/src/devtools.ts | 60 +++++++++++++--------- 2 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 .changeset/fix-4972-devtools-production.md diff --git a/.changeset/fix-4972-devtools-production.md b/.changeset/fix-4972-devtools-production.md new file mode 100644 index 000000000..3ac76efd8 --- /dev/null +++ b/.changeset/fix-4972-devtools-production.md @@ -0,0 +1,5 @@ +--- +"vee-validate": patch +--- + +Fix Vue Devtools code being included in production builds (#4972) diff --git a/packages/vee-validate/src/devtools.ts b/packages/vee-validate/src/devtools.ts index d5bfb1ebe..2d53a4ea8 100644 --- a/packages/vee-validate/src/devtools.ts +++ b/packages/vee-validate/src/devtools.ts @@ -4,41 +4,49 @@ import { PathState, PrivateFieldContext, PrivateFormContext } from './types'; import { isClient, keysOf, setInPath, throttle } from './utils'; import { isObject } from '../../shared'; -const DEVTOOLS_FORMS: Record = {}; -const DEVTOOLS_FIELDS: Record = {}; - -const INSPECTOR_ID = 'vee-validate-inspector'; - -const COLORS = { - error: 0xbd4b4b, - success: 0x06d77b, - unknown: 0x54436b, - white: 0xffffff, - black: 0x000000, - blue: 0x035397, - purple: 0xb980f0, - orange: 0xf5a962, - gray: 0xbbbfca, -}; +let DEVTOOLS_FORMS: Record; +let DEVTOOLS_FIELDS: Record; + +let INSPECTOR_ID: string; + +let COLORS: Record; let SELECTED_NODE: | { type: 'pathState'; form: PrivateFormContext; state: PathState } | { type: 'form'; form: PrivateFormContext & { _vm?: ComponentInternalInstance | null } } | { type: 'field'; field: PrivateFieldContext & { _vm?: ComponentInternalInstance | null } } - | null = null; + | null; /** * Plugin API */ let API: any; +if (__DEV__) { + DEVTOOLS_FORMS = {}; + DEVTOOLS_FIELDS = {}; + INSPECTOR_ID = 'vee-validate-inspector'; + COLORS = { + error: 0xbd4b4b, + success: 0x06d77b, + unknown: 0x54436b, + white: 0xffffff, + black: 0x000000, + blue: 0x035397, + purple: 0xb980f0, + orange: 0xf5a962, + gray: 0xbbbfca, + }; + SELECTED_NODE = null; +} + async function installDevtoolsPlugin(app: App) { if (__DEV__) { if (!isClient) { return; } - const devtools = await import('@vue/devtools-api'); + const devtools = await import(/* @vite-ignore */ '@vue/devtools-api'); devtools.setupDevtoolsPlugin( { id: 'vee-validate-devtools-plugin', @@ -167,13 +175,15 @@ async function installDevtoolsPlugin(app: App) { } } -export const refreshInspector = throttle(() => { - setTimeout(async () => { - await nextTick(); - API?.sendInspectorState(INSPECTOR_ID); - API?.sendInspectorTree(INSPECTOR_ID); - }, 100); -}, 100); +export const refreshInspector = __DEV__ + ? throttle(() => { + setTimeout(async () => { + await nextTick(); + API?.sendInspectorState(INSPECTOR_ID); + API?.sendInspectorTree(INSPECTOR_ID); + }, 100); + }, 100) + : () => {}; export function registerFormWithDevTools(form: PrivateFormContext) { if (!__DEV__ || !isClient) {