svelte-shaker 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/analyze.js CHANGED
@@ -116,6 +116,12 @@ export async function buildAnalyzeInput(entries, resolve, readFile, parseCache,
116
116
  const instance = ast.instance;
117
117
  if (!instance)
118
118
  continue;
119
+ // The bare component tags this file renders (`<Local …>`). Resolving a barrel
120
+ // (a `.js`/`.ts` re-export) means READING and PARSING the target module to
121
+ // chase the export, so we do it ONLY for named imports actually rendered as a
122
+ // component here — a named import used as a value (a helper / type) can never
123
+ // be a `<Local>` call site, so chasing it is pure waste.
124
+ const renderedTags = renderedComponentTagNames(ast);
119
125
  // Resolve this file's imports into the three attributable edge kinds. Direct
120
126
  // default `.svelte` and simple barrel/named imports bind a bare local; a
121
127
  // namespace import (`import * as ns`) binds no single component, so it is
@@ -136,6 +142,9 @@ export async function buildAnalyzeInput(entries, resolve, readFile, parseCache,
136
142
  }
137
143
  continue;
138
144
  }
145
+ // Not rendered as `<imp.local>` -> not a call site -> skip the costly barrel read.
146
+ if (!renderedTags.has(imp.local))
147
+ continue;
139
148
  const childId = await resolveThroughBarrel(imp.value, imp.imported, id, resolve, readFile);
140
149
  if (childId) {
141
150
  edges.push({ from: id, local: imp.local, to: childId, kind: 'barrel' });
@@ -163,9 +172,9 @@ export async function buildAnalyzeInput(entries, resolve, readFile, parseCache,
163
172
  }
164
173
  }
165
174
  // Enqueue every child this file renders: direct `.svelte`, the barrel children
166
- // it renders, and the namespace members it renders.
167
- const rendered = collectBarrelChildIds(ast, barrelLocals);
168
- for (const childId of [...directChildren, ...rendered, ...nsChildren]) {
175
+ // it renders (`barrelLocals` already holds only rendered locals), and the
176
+ // namespace members it renders.
177
+ for (const childId of [...directChildren, ...barrelLocals.values(), ...nsChildren]) {
169
178
  if (!seen.has(childId)) {
170
179
  seen.add(childId);
171
180
  queue.push(childId);
@@ -194,6 +203,10 @@ export function buildAnalyzeInputSync(entries, resolve, readFile, parseCache, pa
194
203
  const instance = ast.instance;
195
204
  if (!instance)
196
205
  continue;
206
+ // See {@link buildAnalyzeInput}: resolve a barrel only for named imports
207
+ // actually rendered as a `<Local>` component here, to avoid reading+parsing
208
+ // modules behind value-only named imports.
209
+ const renderedTags = renderedComponentTagNames(ast);
197
210
  const barrelLocals = new Map();
198
211
  const namespaceSources = new Map();
199
212
  const directChildren = [];
@@ -210,6 +223,8 @@ export function buildAnalyzeInputSync(entries, resolve, readFile, parseCache, pa
210
223
  }
211
224
  continue;
212
225
  }
226
+ if (!renderedTags.has(imp.local))
227
+ continue;
213
228
  const childId = resolveThroughBarrelSync(imp.value, imp.imported, id, resolve, readFile);
214
229
  if (childId) {
215
230
  edges.push({ from: id, local: imp.local, to: childId, kind: 'barrel' });
@@ -230,8 +245,7 @@ export function buildAnalyzeInputSync(entries, resolve, readFile, parseCache, pa
230
245
  }
231
246
  }
232
247
  }
233
- const rendered = collectBarrelChildIds(ast, barrelLocals);
234
- for (const childId of [...directChildren, ...rendered, ...nsChildren]) {
248
+ for (const childId of [...directChildren, ...barrelLocals.values(), ...nsChildren]) {
235
249
  if (!seen.has(childId)) {
236
250
  seen.add(childId);
237
251
  queue.push(childId);
@@ -786,24 +800,25 @@ function collectChildCalls(ast, imports) {
786
800
  return calls;
787
801
  }
788
802
  /**
789
- * The set of barrel-resolved children this file actually RENDERS as `<Comp/>`.
790
- * Used by the Shell crawl to enqueue only the barrel children a file renders — an
791
- * unused barrel import resolves to a component nothing instantiates, so following
792
- * it would pull a never-rendered file into the program for no reason.
803
+ * The bare component tag names this file RENDERS (`<Local/>`, excluding dotted
804
+ * `<ns.X/>` member tags). The Shell crawl uses this to resolve a barrel (a
805
+ * `.js`/`.ts` re-export, which costs a module read+parse) only for named imports
806
+ * actually rendered as a component — a value-only named import (a helper / type)
807
+ * is never a `<Local>` call site, so following it would read+parse a module for
808
+ * nothing. Skipping it only ever drops a non-call-site, so attribution (and the
809
+ * resulting models) are unchanged.
793
810
  */
794
- function collectBarrelChildIds(ast, barrelLocals) {
795
- const ids = new Set();
796
- if (barrelLocals.size === 0)
797
- return ids;
811
+ function renderedComponentTagNames(ast) {
812
+ const names = new Set();
798
813
  walk(ast.fragment, null, {
799
814
  Component(node, { next }) {
800
- const childId = node.name ? barrelLocals.get(node.name) : undefined;
801
- if (childId)
802
- ids.add(childId);
815
+ if (typeof node.name === 'string' && node.name !== '' && !node.name.includes('.')) {
816
+ names.add(node.name);
817
+ }
803
818
  next();
804
819
  },
805
820
  });
806
- return ids;
821
+ return names;
807
822
  }
808
823
  /**
809
824
  * Every dotted component tag a file renders (`<ns.Child/>` -> `"ns.Child"`). The
@@ -51,6 +51,27 @@ function analyze_program(input_json) {
51
51
  }
52
52
  exports.analyze_program = analyze_program;
53
53
 
54
+ /**
55
+ * JSON-string wrapper of {@link find_never_passed_props} for the WASM boundary.
56
+ * @param {string} input_json
57
+ * @returns {string}
58
+ */
59
+ function find_never_passed_props_json(input_json) {
60
+ let deferred2_0;
61
+ let deferred2_1;
62
+ try {
63
+ const ptr0 = passStringToWasm0(input_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
64
+ const len0 = WASM_VECTOR_LEN;
65
+ const ret = wasm.find_never_passed_props_json(ptr0, len0);
66
+ deferred2_0 = ret[0];
67
+ deferred2_1 = ret[1];
68
+ return getStringFromWasm0(ret[0], ret[1]);
69
+ } finally {
70
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
71
+ }
72
+ }
73
+ exports.find_never_passed_props_json = find_never_passed_props_json;
74
+
54
75
  /**
55
76
  * Whole-program shake: analyze + transform. `input` is `{ files: [{id, ast,
56
77
  * code}], edges, entries }`. Returns `{ id: slimmedSource }` for every file —
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-shaker",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "Tree shaking for Svelte components",
5
5
  "keywords": [
6
6
  "dead-code-elimination",