Skip to content

Commit e1ffd09

Browse files
authored
feat(rolldown-vite): enable optimization.inlineConst by default (#1207)
* feat(rolldown-vite): enable optimization.inlineConst by default * add warning log if inlineConst is disabled * refactor: reuse semver comparator and document why we only apply inlineConst after 1.0.0-beta.35 * fix: support comparing partial version strings (missing tag,patch,minor)
1 parent 818087d commit e1ffd09

File tree

4 files changed

+89
-3
lines changed

4 files changed

+89
-3
lines changed

.changeset/all-colts-dig.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/vite-plugin-svelte': minor
3+
---
4+
5+
feat(rolldown-vite): enable `optimization.inlineConst` by default to ensure treeshaking works with esm-env in svelte

packages/vite-plugin-svelte/__tests__/svelte-version.spec.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,54 @@ import { describe, it, expect } from 'vitest';
22
import { gte } from '../src/utils/svelte-version.js';
33

44
describe('gte', () => {
5+
it('returns false for smaller tag', () => {
6+
expect(gte('1.2.3-next.1', '1.2.3-next.2')).toBe(false);
7+
});
8+
it('returns false for tag vs no tag', () => {
9+
expect(gte('1.2.3-next.0', '1.2.3')).toBe(false);
10+
});
511
it('returns false for smaller patch', () => {
12+
expect(gte('1.2.2-next.0', '1.2.3')).toBe(false);
613
expect(gte('1.2.2', '1.2.3')).toBe(false);
714
});
815
it('returns false for smaller minor', () => {
16+
expect(gte('1.1.4-next.0', '1.2.3')).toBe(false);
917
expect(gte('1.1.4', '1.2.3')).toBe(false);
18+
expect(gte('1.1', '1.2.3')).toBe(false);
1019
});
1120
it('returns false for smaller major', () => {
21+
expect(gte('0.3.4-next.0', '1.2.3')).toBe(false);
1222
expect(gte('0.3.4', '1.2.3')).toBe(false);
23+
expect(gte('0.3', '1.2.3')).toBe(false);
24+
expect(gte('0', '1.2.3')).toBe(false);
1325
});
1426
it('returns true for equal', () => {
27+
expect(gte('1.2.3-next.1', '1.2.3-next.1')).toBe(true);
28+
});
29+
it('returns true for equal without tag', () => {
1530
expect(gte('1.2.3', '1.2.3')).toBe(true);
31+
expect(gte('1.2', '1.2.0')).toBe(true);
32+
expect(gte('1.2', '1.2')).toBe(true);
33+
expect(gte('1', '1.0')).toBe(true);
34+
expect(gte('1', '1.0.0')).toBe(true);
35+
});
36+
it('returns true for larger tag', () => {
37+
expect(gte('1.2.3-next.2', '1.2.3-next.1')).toBe(true);
38+
});
39+
it('returns true for no tag vs tag', () => {
40+
expect(gte('1.2.3', '1.2.3-next.0')).toBe(true);
1641
});
1742
it('returns true for larger patch', () => {
1843
expect(gte('1.2.4', '1.2.3')).toBe(true);
44+
expect(gte('1.2.4-next.0', '1.2.3')).toBe(true);
1945
});
2046
it('returns true for larger minor', () => {
2147
expect(gte('1.3.1', '1.2.3')).toBe(true);
48+
expect(gte('1.3', '1.2.3')).toBe(true);
2249
});
2350
it('returns true for larger major', () => {
2451
expect(gte('2.0.0', '1.2.3')).toBe(true);
52+
expect(gte('2.0', '1.2.3')).toBe(true);
53+
expect(gte('2', '1.2.3')).toBe(true);
2554
});
2655
});

packages/vite-plugin-svelte/src/plugins/configure.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from '../utils/options.js';
1313
import { buildIdFilter, buildIdParser } from '../utils/id.js';
1414
import { createCompileSvelte } from '../utils/compile.js';
15+
import { gte } from '../utils/svelte-version.js';
1516

1617
// @ts-ignore rolldownVersion
1718
const { version: viteVersion, rolldownVersion } = vite;
@@ -58,7 +59,39 @@ export function configure(api, inlineOptions) {
5859
preOptions = await preResolveOptions(inlineOptions, config, configEnv);
5960
// extra vite config
6061
const extraViteConfig = await buildExtraViteConfig(preOptions, config);
62+
63+
if (
64+
rolldownVersion &&
65+
configEnv.command === 'build' &&
66+
gte(rolldownVersion, '1.0.0-beta.35') // inlineConst received a critical bugfix in 1.0.0-beta.35
67+
) {
68+
extraViteConfig.build ??= {};
69+
// rename rollupOptions to rolldownOptions
70+
//@ts-ignore rolldownOptions only exists in rolldown-vite
71+
extraViteConfig.build.rolldownOptions = extraViteConfig.build.rollupOptions || {};
72+
delete extraViteConfig.build.rollupOptions;
73+
// read user config inlineConst value
74+
const inlineConst =
75+
//@ts-ignore optimization only exists in rolldown-vite
76+
config.build?.rolldownOptions?.optimization?.inlineConst ??
77+
//@ts-ignore optimization only exists in rolldown-vite
78+
config.build?.rollupOptions?.optimization?.inlineConst;
79+
80+
if (inlineConst == null) {
81+
// set inlineConst build optimization for esm-env
82+
//@ts-ignore rolldownOptions only exists in rolldown-vite
83+
extraViteConfig.build.rolldownOptions.optimization ??= {};
84+
//@ts-ignore rolldownOptions only exists in rolldown-vite
85+
extraViteConfig.build.rolldownOptions.optimization.inlineConst = true;
86+
} else if (inlineConst === false) {
87+
log.warn(
88+
'Your rolldown config contains `optimization.inlineConst: false`. This can lead to increased bundle size and leaked server code in client build.'
89+
);
90+
}
91+
}
92+
6193
log.debug('additional vite config', extraViteConfig, 'config');
94+
6295
return extraViteConfig;
6396
}
6497
},

packages/vite-plugin-svelte/src/utils/svelte-version.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,34 @@ import { VERSION } from 'svelte/compiler';
66
export const isSvelteWithAsync = gte(VERSION, '5.36.0');
77

88
/**
9-
* compare semver versions, does not include comparing tags (-next.xy is ignored)
9+
* split semver string and convert to number, ignores non digits in tag
10+
* @param {string} semver
11+
* @return {number[]} [major,minor,patch,tag]
12+
*/
13+
function splitToNumbers(semver) {
14+
const num = semver
15+
.replace(/[^\d.-]/g, '')
16+
.split(/[.-]+/, 4)
17+
.map(Number);
18+
while (num.length < 3) {
19+
num.push(0);
20+
}
21+
if (num.length < 4) {
22+
num.push(Infinity);
23+
}
24+
return num;
25+
}
26+
27+
/**
28+
* compare semver versions, tags are compared by their numeric part only
1029
*
1130
* @param {string} a semver version
1231
* @param {string} b semver version
1332
* @return {boolean} true if a is greater or equal to b
1433
*/
1534
export function gte(a, b) {
16-
const aNum = a.split(/[.-]/, 3).map(Number);
17-
const bNum = b.split(/[.-]/, 3).map(Number);
35+
const aNum = splitToNumbers(a);
36+
const bNum = splitToNumbers(b);
1837
for (let i = 0; i < aNum.length; i++) {
1938
if (aNum[i] < bNum[i]) {
2039
return false;

0 commit comments

Comments
 (0)