Skip to content

Commit 555e8f8

Browse files
authored
enforce treeshakeability (#9430)
* enforce treeshakeability * fix * appease the dweeby little hall monitor --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 455fa89 commit 555e8f8

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
lines changed

packages/svelte/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
"templating"
9191
],
9292
"scripts": {
93-
"build": "rollup -c && node scripts/build.js",
93+
"build": "rollup -c && node scripts/build.js && node scripts/check-treeshakeability.js",
9494
"watch": "rollup -cw",
9595
"check": "tsc && cd ./tests/types && tsc",
9696
"check:watch": "tsc --watch",
@@ -103,6 +103,7 @@
103103
"@rollup/plugin-commonjs": "^25.0.7",
104104
"@rollup/plugin-node-resolve": "^15.2.3",
105105
"@rollup/plugin-terser": "^0.4.4",
106+
"@rollup/plugin-virtual": "^3.0.2",
106107
"@types/aria-query": "^5.0.3",
107108
"@types/estree": "^1.0.5",
108109
"dts-buddy": "^0.4.0",
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import fs from 'node:fs';
2+
import path from 'node:path';
3+
import { rollup } from 'rollup';
4+
import virtual from '@rollup/plugin-virtual';
5+
6+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
7+
8+
let failed = false;
9+
10+
// eslint-disable-next-line no-console
11+
console.group('checking treeshakeability');
12+
13+
for (const key in pkg.exports) {
14+
// special cases
15+
if (key === './compiler') continue;
16+
if (key === './internal/disclose-version') continue;
17+
18+
for (const type of ['browser', 'default']) {
19+
if (!pkg.exports[key][type]) continue;
20+
21+
const subpackage = path.join(pkg.name, key);
22+
23+
const resolved = path.resolve(pkg.exports[key][type]);
24+
25+
const bundle = await rollup({
26+
input: '__entry__',
27+
plugins: [
28+
virtual({
29+
__entry__: `import ${JSON.stringify(resolved)}`
30+
})
31+
],
32+
onwarn: (warning, handle) => {
33+
// if (warning.code !== 'EMPTY_BUNDLE') handle(warning);
34+
}
35+
});
36+
37+
const { output } = await bundle.generate({});
38+
39+
if (output.length > 1) {
40+
throw new Error('errr what');
41+
}
42+
43+
const code = output[0].code.replace(/import\s+([^'"]+from\s+)?(['"])[^'"]+\2\s*;?/, '');
44+
if (code.trim()) {
45+
// eslint-disable-next-line no-console
46+
console.error(code);
47+
// eslint-disable-next-line no-console
48+
console.error(`❌ ${subpackage} (${type})`);
49+
failed = true;
50+
} else {
51+
// eslint-disable-next-line no-console
52+
console.error(`✅ ${subpackage} (${type})`);
53+
}
54+
}
55+
}
56+
57+
// eslint-disable-next-line no-console
58+
console.groupEnd();
59+
60+
if (failed) {
61+
process.exit(1);
62+
}

packages/svelte/src/internal/server/index.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const INVALID_ATTR_NAME_CHAR_REGEX =
3232
/[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
3333

3434
// This is duplicated from the compiler, but we need it at runtime too.
35-
const DOMBooleans = [
35+
export const DOMBooleanAttributes = [
3636
'allowfullscreen',
3737
'async',
3838
'autofocus',
@@ -59,9 +59,6 @@ const DOMBooleans = [
5959
'selected'
6060
];
6161

62-
/** @type {Set<string>} */
63-
export const DOMBooleanAttributes = new Set(DOMBooleans);
64-
6562
export const VoidElements = new Set([
6663
'area',
6764
'base',
@@ -280,7 +277,7 @@ export function spread_attributes(attrs, class_hash, additional) {
280277

281278
for (name in merged_attrs) {
282279
if (INVALID_ATTR_NAME_CHAR_REGEX.test(name)) continue;
283-
const is_boolean = DOMBooleanAttributes.has(name);
280+
const is_boolean = DOMBooleanAttributes.includes(name);
284281
attr_str += attr(name, merged_attrs[name], is_boolean);
285282
}
286283

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)