Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/warm-snakes-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

chore: adds legacy mode flag reducing bundle size in runes mode only apps
3 changes: 3 additions & 0 deletions packages/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
"./internal/disclose-version": {
"default": "./src/internal/disclose-version.js"
},
"./internal/flags/legacy": {
"default": "./src/internal/flags/legacy.js"
},
"./internal/server": {
"default": "./src/internal/server/index.js"
},
Expand Down
17 changes: 15 additions & 2 deletions packages/svelte/scripts/check-treeshakeability.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ for (const key in pkg.exports) {
if (key === './compiler') continue;
if (key === './internal') continue;
if (key === './internal/disclose-version') continue;
if (key === './internal/flags/legacy') continue;

for (const type of ['browser', 'default']) {
if (!pkg.exports[key][type]) continue;
Expand All @@ -83,6 +84,7 @@ const bundle = await bundle_code(
// Use all features which contain hydration code to ensure it's treeshakeable
compile(
`
<svelte:options runes />
<script>
import { mount } from ${JSON.stringify(client_main)}; mount();
let foo;
Expand Down Expand Up @@ -118,12 +120,23 @@ if (!bundle.includes('hydrate_node') && !bundle.includes('hydrate_next')) {
// eslint-disable-next-line no-console
console.error(`✅ Hydration code treeshakeable`);
} else {
// eslint-disable-next-line no-console
console.error(bundle);
failed = true;
// eslint-disable-next-line no-console
console.error(`❌ Hydration code not treeshakeable`);
}

if (!bundle.includes('component_context.l')) {
// eslint-disable-next-line no-console
console.error(`✅ Legacy code treeshakeable`);
} else {
failed = true;
// eslint-disable-next-line no-console
console.error(`❌ Legacy code not treeshakeable`);
}

if (failed) {
// eslint-disable-next-line no-console
console.error(bundle);
fs.writeFileSync('scripts/_bundle.js', bundle);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,10 @@ export function client_component(analysis, options) {
body.push(b.stmt(b.call(b.id('$.mark_module_end'), b.id(analysis.name))));
}

if (!analysis.runes) {
body.unshift(b.imports([], 'svelte/internal/flags/legacy'));
}

if (options.discloseVersion) {
body.unshift(b.imports([], 'svelte/internal/disclose-version'));
}
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/src/index-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { is_array } from './internal/shared/utils.js';
import { user_effect } from './internal/client/index.js';
import * as e from './internal/client/errors.js';
import { lifecycle_outside_component } from './internal/shared/errors.js';
import { legacy_mode_flag } from './internal/flags/index.js';

/**
* The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.
Expand All @@ -25,7 +26,7 @@ export function onMount(fn) {
lifecycle_outside_component('onMount');
}

if (component_context.l !== null) {
if (legacy_mode_flag && component_context.l !== null) {
init_update_callbacks(component_context).m.push(fn);
} else {
user_effect(() => {
Expand Down
38 changes: 19 additions & 19 deletions packages/svelte/src/internal/client/dom/blocks/each.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,27 +490,27 @@ function update_item(item, value, index, type) {
*/
function create_item(anchor, state, prev, next, value, key, index, render_fn, flags) {
var previous_each_item = current_each_item;
var reactive = (flags & EACH_ITEM_REACTIVE) !== 0;
var mutable = (flags & EACH_ITEM_IMMUTABLE) === 0;

var v = reactive ? (mutable ? mutable_source(value) : source(value)) : value;
var i = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index);

/** @type {EachItem} */
var item = {
i,
v,
k: key,
a: null,
// @ts-expect-error
e: null,
prev,
next
};

current_each_item = item;

try {
var reactive = (flags & EACH_ITEM_REACTIVE) !== 0;
var mutable = (flags & EACH_ITEM_IMMUTABLE) === 0;

var v = reactive ? (mutable ? mutable_source(value) : source(value)) : value;
var i = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index);

/** @type {EachItem} */
var item = {
i,
v,
k: key,
a: null,
// @ts-expect-error
e: null,
prev,
next
};

current_each_item = item;
item.e = branch(() => render_fn(anchor, v, i), hydrating);

item.e.prev = prev && prev.e;
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/src/internal/client/reactivity/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as e from '../errors.js';
import { BRANCH_EFFECT, LEGACY_DERIVED_PROP, ROOT_EFFECT } from '../constants.js';
import { proxy } from '../proxy.js';
import { capture_store_binding } from './store.js';
import { legacy_mode_flag } from '../../flags/index.js';

/**
* @param {((value?: number) => number)} fn
Expand Down Expand Up @@ -270,7 +271,7 @@ function with_parent_branch(fn) {
*/
export function prop(props, key, flags, fallback) {
var immutable = (flags & PROPS_IS_IMMUTABLE) !== 0;
var runes = (flags & PROPS_IS_RUNES) !== 0;
var runes = !legacy_mode_flag || (flags & PROPS_IS_RUNES) !== 0;
var bindable = (flags & PROPS_IS_BINDABLE) !== 0;
var lazy = (flags & PROPS_IS_LAZY_INITIAL) !== 0;
var is_store_sub = false;
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/src/internal/client/reactivity/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
BLOCK_EFFECT
} from '../constants.js';
import * as e from '../errors.js';
import { legacy_mode_flag } from '../../flags/index.js';

export let inspect_effects = new Set();

Expand Down Expand Up @@ -80,7 +81,7 @@ export function mutable_source(initial_value, immutable = false) {

// bind the signal to the component context, in case we need to
// track updates to trigger beforeUpdate/afterUpdate callbacks
if (component_context !== null && component_context.l !== null) {
if (legacy_mode_flag && component_context !== null && component_context.l !== null) {
(component_context.l.s ??= []).push(s);
}

Expand Down
5 changes: 3 additions & 2 deletions packages/svelte/src/internal/client/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,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';

const FLUSH_MICROTASK = 0;
const FLUSH_SYNC = 1;
Expand Down Expand Up @@ -162,7 +163,7 @@ export function increment_version() {

/** @returns {boolean} */
export function is_runes() {
return component_context !== null && component_context.l === null;
return !legacy_mode_flag || (component_context !== null && component_context.l === null);
}

/**
Expand Down Expand Up @@ -1025,7 +1026,7 @@ export function push(props, runes = false, fn) {
l: null
};

if (!runes) {
if (legacy_mode_flag && !runes) {
component_context.l = {
s: null,
u: null,
Expand Down
5 changes: 5 additions & 0 deletions packages/svelte/src/internal/flags/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export let legacy_mode_flag = false;

export function enable_legacy_mode_flag() {
legacy_mode_flag = true;
}
3 changes: 3 additions & 0 deletions packages/svelte/src/internal/flags/legacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { enable_legacy_mode_flag } from './index.js';

enable_legacy_mode_flag();
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@

</script>

{count} / {doubled} / {quadrupled} / {time_8} / {time_16}
{count} / {doubled} / {quadrupled} / {time_8} / {time_16}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@
{readonly}
{optional}
<input bind:value={binding} />
<input bind:value={bindingOptional} />
<input bind:value={bindingOptional} />
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "svelte/internal/disclose-version";
import "svelte/internal/flags/legacy";
import * as $ from "svelte/internal/client";

export default function Bind_this($$anchor) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "svelte/internal/disclose-version";
import "svelte/internal/flags/legacy";
import * as $ from "svelte/internal/client";

export default function Each_string_template($$anchor) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "svelte/internal/disclose-version";
import "svelte/internal/flags/legacy";
import * as $ from "svelte/internal/client";

var root = $.template(`<h1>hello world</h1>`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "svelte/internal/disclose-version";
import "svelte/internal/flags/legacy";
import * as $ from "svelte/internal/client";

var root = $.template(`<h1>hello world</h1>`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "svelte/internal/disclose-version";
import "svelte/internal/flags/legacy";
import * as $ from "svelte/internal/client";
import { random } from './module.svelte';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "svelte/internal/disclose-version";
import "svelte/internal/flags/legacy";
import * as $ from "svelte/internal/client";

var root = $.template(`<p></p> <p></p> <!>`, 1);
Expand Down
Loading