diff --git a/.changeset/tough-dingos-deliver.md b/.changeset/tough-dingos-deliver.md
new file mode 100644
index 000000000000..5c0faf703c6f
--- /dev/null
+++ b/.changeset/tough-dingos-deliver.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: treeshake `$inspect.trace` code if unused
diff --git a/packages/svelte/package.json b/packages/svelte/package.json
index 1b3df47bdf94..6e6075c5db76 100644
--- a/packages/svelte/package.json
+++ b/packages/svelte/package.json
@@ -56,6 +56,9 @@
"./internal/flags/legacy": {
"default": "./src/internal/flags/legacy.js"
},
+ "./internal/flags/tracing": {
+ "default": "./src/internal/flags/tracing.js"
+ },
"./internal/server": {
"default": "./src/internal/server/index.js"
},
diff --git a/packages/svelte/scripts/check-treeshakeability.js b/packages/svelte/scripts/check-treeshakeability.js
index 1b50111b8755..1501ee69546d 100644
--- a/packages/svelte/scripts/check-treeshakeability.js
+++ b/packages/svelte/scripts/check-treeshakeability.js
@@ -58,6 +58,7 @@ for (const key in pkg.exports) {
if (key === './internal') continue;
if (key === './internal/disclose-version') continue;
if (key === './internal/flags/legacy') continue;
+ if (key === './internal/flags/tracing') continue;
for (const type of ['browser', 'default']) {
if (!pkg.exports[key][type]) continue;
@@ -91,6 +92,7 @@ const bundle = await bundle_code(
hi
+
a
a
@@ -134,6 +136,15 @@ if (!bundle.includes('component_context.l')) {
console.error(`❌ Legacy code not treeshakeable`);
}
+if (!bundle.includes(`'CreatedAt'`)) {
+ // eslint-disable-next-line no-console
+ console.error(`✅ $inspect.trace code treeshakeable`);
+} else {
+ failed = true;
+ // eslint-disable-next-line no-console
+ console.error(`❌ $inspect.trace code not treeshakeable`);
+}
+
if (failed) {
// eslint-disable-next-line no-console
console.error(bundle);
diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js
index 042e88fa2f83..a4167be3a1c8 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/index.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/index.js
@@ -408,6 +408,7 @@ export function analyze_component(root, source, options) {
template,
elements: [],
runes,
+ tracing: false,
immutable: runes || options.immutable,
exports: [],
uses_props: false,
diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js
index 6a301726b106..9f51cd61de6d 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js
@@ -171,6 +171,8 @@ export function CallExpression(node, context) {
context.state.scope.tracing = b.thunk(b.literal(label + ' ' + loc));
}
+
+ context.state.analysis.tracing = true;
}
break;
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js
index ccbdcea4cc56..8e05b44a839e 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js
@@ -539,6 +539,10 @@ export function client_component(analysis, options) {
body.unshift(b.imports([], 'svelte/internal/flags/legacy'));
}
+ if (analysis.tracing) {
+ body.unshift(b.imports([], 'svelte/internal/flags/tracing'));
+ }
+
if (options.discloseVersion) {
body.unshift(b.imports([], 'svelte/internal/disclose-version'));
}
diff --git a/packages/svelte/src/compiler/phases/types.d.ts b/packages/svelte/src/compiler/phases/types.d.ts
index 6a2ea27993e1..b4dcc270cd26 100644
--- a/packages/svelte/src/compiler/phases/types.d.ts
+++ b/packages/svelte/src/compiler/phases/types.d.ts
@@ -39,6 +39,7 @@ export interface ComponentAnalysis extends Analysis {
/** Used for CSS pruning and scoping */
elements: Array;
runes: boolean;
+ tracing: boolean;
exports: Array<{ name: string; alias: string | null }>;
/** Whether the component uses `$$props` */
uses_props: boolean;
diff --git a/packages/svelte/src/internal/client/proxy.js b/packages/svelte/src/internal/client/proxy.js
index d74f55866f20..6cbd6394df3a 100644
--- a/packages/svelte/src/internal/client/proxy.js
+++ b/packages/svelte/src/internal/client/proxy.js
@@ -14,6 +14,7 @@ import { STATE_SYMBOL, STATE_SYMBOL_METADATA } from './constants.js';
import { UNINITIALIZED } from '../../constants.js';
import * as e from './errors.js';
import { get_stack } from './dev/tracing.js';
+import { tracing_mode_flag } from '../flags/index.js';
/**
* @template T
@@ -25,7 +26,7 @@ import { get_stack } from './dev/tracing.js';
export function proxy(value, parent = null, prev) {
/** @type {Error | null} */
var stack = null;
- if (DEV) {
+ if (DEV && tracing_mode_flag) {
stack = get_stack('CreatedAt');
}
// if non-proxyable, or is already a proxy, return `value`
diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js
index 8c1a3a652b5b..5e045920bf61 100644
--- a/packages/svelte/src/internal/client/reactivity/deriveds.js
+++ b/packages/svelte/src/internal/client/reactivity/deriveds.js
@@ -25,6 +25,7 @@ import * as e from '../errors.js';
import { destroy_effect } from './effects.js';
import { inspect_effects, set_inspect_effects } from './sources.js';
import { get_stack } from '../dev/tracing.js';
+import { tracing_mode_flag } from '../../flags/index.js';
/**
* @template V
@@ -62,7 +63,7 @@ export function derived(fn) {
parent: parent_derived ?? active_effect
};
- if (DEV) {
+ if (DEV && tracing_mode_flag) {
signal.created = get_stack('CreatedAt');
}
diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js
index 24dd837772b6..3e8c4a00c833 100644
--- a/packages/svelte/src/internal/client/reactivity/sources.js
+++ b/packages/svelte/src/internal/client/reactivity/sources.js
@@ -32,7 +32,7 @@ import {
BLOCK_EFFECT
} from '../constants.js';
import * as e from '../errors.js';
-import { legacy_mode_flag } from '../../flags/index.js';
+import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js';
import { get_stack } from '../dev/tracing.js';
export let inspect_effects = new Set();
@@ -60,7 +60,7 @@ export function source(v, stack) {
version: 0
};
- if (DEV) {
+ if (DEV && tracing_mode_flag) {
signal.created = stack ?? get_stack('CreatedAt');
signal.debug = null;
}
@@ -170,7 +170,7 @@ export function internal_set(source, value) {
source.v = value;
source.version = increment_version();
- if (DEV) {
+ if (DEV && tracing_mode_flag) {
source.updated = get_stack('UpdatedAt');
}
diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js
index 4aa3d17a15e8..4a90a219712f 100644
--- a/packages/svelte/src/internal/client/runtime.js
+++ b/packages/svelte/src/internal/client/runtime.js
@@ -34,7 +34,7 @@ import { destroy_derived, execute_derived, update_derived } from './reactivity/d
import * as e from './errors.js';
import { lifecycle_outside_component } from '../shared/errors.js';
import { FILENAME } from '../../constants.js';
-import { legacy_mode_flag } from '../flags/index.js';
+import { legacy_mode_flag, tracing_mode_flag } from '../flags/index.js';
import { tracing_expressions, get_stack } from './dev/tracing.js';
const FLUSH_MICROTASK = 0;
@@ -917,6 +917,7 @@ export function get(signal) {
if (
DEV &&
+ tracing_mode_flag &&
tracing_expressions !== null &&
active_reaction !== null &&
tracing_expressions.reaction === active_reaction
diff --git a/packages/svelte/src/internal/flags/index.js b/packages/svelte/src/internal/flags/index.js
index 767a40a76543..017840f2d967 100644
--- a/packages/svelte/src/internal/flags/index.js
+++ b/packages/svelte/src/internal/flags/index.js
@@ -1,5 +1,10 @@
export let legacy_mode_flag = false;
+export let tracing_mode_flag = false;
export function enable_legacy_mode_flag() {
legacy_mode_flag = true;
}
+
+export function enable_tracing_mode_flag() {
+ tracing_mode_flag = true;
+}
diff --git a/packages/svelte/src/internal/flags/tracing.js b/packages/svelte/src/internal/flags/tracing.js
new file mode 100644
index 000000000000..b2de46dcd11b
--- /dev/null
+++ b/packages/svelte/src/internal/flags/tracing.js
@@ -0,0 +1,3 @@
+import { enable_tracing_mode_flag } from './index.js';
+
+enable_tracing_mode_flag();