@tanstack/router-plugin 1.159.10 → 1.159.12

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.
@@ -2,7 +2,7 @@ import * as t from "@babel/types";
2
2
  import babel from "@babel/core";
3
3
  import * as template from "@babel/template";
4
4
  import { parseAst, findReferencedIdentifiers, deadCodeElimination, generateFromAst } from "@tanstack/router-utils";
5
- import { tsrSplit } from "../constants.js";
5
+ import { tsrShared, tsrSplit } from "../constants.js";
6
6
  import { routeHmrStatement } from "../route-hmr-statement.js";
7
7
  import { createIdentifier } from "./path-ids.js";
8
8
  import { getFrameworkOptions } from "./framework-options.js";
@@ -85,6 +85,10 @@ function removeSplitSearchParamFromFilename(filename) {
85
85
  const [bareFilename] = filename.split("?");
86
86
  return bareFilename;
87
87
  }
88
+ function addSharedSearchParamToFilename(filename) {
89
+ const [bareFilename] = filename.split("?");
90
+ return `${bareFilename}?${tsrShared}=1`;
91
+ }
88
92
  const splittableCreateRouteFns = ["createFileRoute"];
89
93
  const unsplittableCreateRouteFns = [
90
94
  "createRootRoute",
@@ -94,6 +98,304 @@ const allCreateRouteFns = [
94
98
  ...splittableCreateRouteFns,
95
99
  ...unsplittableCreateRouteFns
96
100
  ];
101
+ function collectIdentifiersFromNode(node) {
102
+ const ids = /* @__PURE__ */ new Set();
103
+ (function walk(n, parent, grandparent, parentKey) {
104
+ if (!n) return;
105
+ if (t.isIdentifier(n)) {
106
+ if (!parent || t.isReferenced(n, parent, grandparent)) {
107
+ ids.add(n.name);
108
+ }
109
+ return;
110
+ }
111
+ if (t.isJSXIdentifier(n)) {
112
+ if (parent && t.isJSXAttribute(parent) && parentKey === "name") {
113
+ return;
114
+ }
115
+ if (parent && t.isJSXMemberExpression(parent) && parentKey === "property") {
116
+ return;
117
+ }
118
+ const first = n.name[0];
119
+ if (first && first === first.toLowerCase()) {
120
+ return;
121
+ }
122
+ ids.add(n.name);
123
+ return;
124
+ }
125
+ for (const key of t.VISITOR_KEYS[n.type] || []) {
126
+ const child = n[key];
127
+ if (Array.isArray(child)) {
128
+ for (const c of child) {
129
+ if (c && typeof c.type === "string") {
130
+ walk(c, n, parent, key);
131
+ }
132
+ }
133
+ } else if (child && typeof child.type === "string") {
134
+ walk(child, n, parent, key);
135
+ }
136
+ }
137
+ })(node);
138
+ return ids;
139
+ }
140
+ function buildDeclarationMap(ast) {
141
+ const map = /* @__PURE__ */ new Map();
142
+ for (const stmt of ast.program.body) {
143
+ const decl = t.isExportNamedDeclaration(stmt) && stmt.declaration ? stmt.declaration : stmt;
144
+ if (t.isVariableDeclaration(decl)) {
145
+ for (const declarator of decl.declarations) {
146
+ for (const name of collectIdentifiersFromPattern(declarator.id)) {
147
+ map.set(name, declarator);
148
+ }
149
+ }
150
+ } else if (t.isFunctionDeclaration(decl) && decl.id) {
151
+ map.set(decl.id.name, decl);
152
+ } else if (t.isClassDeclaration(decl) && decl.id) {
153
+ map.set(decl.id.name, decl);
154
+ }
155
+ }
156
+ return map;
157
+ }
158
+ function buildDependencyGraph(declMap, localBindings) {
159
+ const graph = /* @__PURE__ */ new Map();
160
+ for (const [name, declNode] of declMap) {
161
+ if (!localBindings.has(name)) continue;
162
+ const allIds = collectIdentifiersFromNode(declNode);
163
+ const deps = /* @__PURE__ */ new Set();
164
+ for (const id of allIds) {
165
+ if (id !== name && localBindings.has(id)) deps.add(id);
166
+ }
167
+ graph.set(name, deps);
168
+ }
169
+ return graph;
170
+ }
171
+ function computeSharedBindings(opts) {
172
+ const ast = parseAst(opts);
173
+ const localModuleLevelBindings = /* @__PURE__ */ new Set();
174
+ for (const node of ast.program.body) {
175
+ collectLocalBindingsFromStatement(node, localModuleLevelBindings);
176
+ }
177
+ localModuleLevelBindings.delete("Route");
178
+ if (localModuleLevelBindings.size === 0) {
179
+ return /* @__PURE__ */ new Set();
180
+ }
181
+ function findIndexForSplitNode(str) {
182
+ return opts.codeSplitGroupings.findIndex(
183
+ (group) => group.includes(str)
184
+ );
185
+ }
186
+ let routeOptions;
187
+ babel.traverse(ast, {
188
+ CallExpression(path) {
189
+ if (!t.isIdentifier(path.node.callee)) return;
190
+ if (!splittableCreateRouteFns.includes(path.node.callee.name)) return;
191
+ if (t.isCallExpression(path.parentPath.node)) {
192
+ const opts2 = resolveIdentifier(path, path.parentPath.node.arguments[0]);
193
+ if (t.isObjectExpression(opts2)) routeOptions = opts2;
194
+ } else if (t.isVariableDeclarator(path.parentPath.node)) {
195
+ const caller = resolveIdentifier(path, path.parentPath.node.init);
196
+ if (t.isCallExpression(caller)) {
197
+ const opts2 = resolveIdentifier(path, caller.arguments[0]);
198
+ if (t.isObjectExpression(opts2)) routeOptions = opts2;
199
+ }
200
+ }
201
+ }
202
+ });
203
+ if (!routeOptions) return /* @__PURE__ */ new Set();
204
+ const splitGroupsPresent = /* @__PURE__ */ new Set();
205
+ let hasNonSplit = false;
206
+ for (const prop of routeOptions.properties) {
207
+ if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) continue;
208
+ if (prop.key.name === "codeSplitGroupings") continue;
209
+ if (t.isIdentifier(prop.value) && prop.value.name === "undefined") continue;
210
+ const groupIndex = findIndexForSplitNode(prop.key.name);
211
+ if (groupIndex === -1) {
212
+ hasNonSplit = true;
213
+ } else {
214
+ splitGroupsPresent.add(groupIndex);
215
+ }
216
+ }
217
+ if (!hasNonSplit && splitGroupsPresent.size < 2) return /* @__PURE__ */ new Set();
218
+ const declMap = buildDeclarationMap(ast);
219
+ const depGraph = buildDependencyGraph(declMap, localModuleLevelBindings);
220
+ const allLocalBindings = new Set(localModuleLevelBindings);
221
+ allLocalBindings.add("Route");
222
+ const fullDepGraph = buildDependencyGraph(declMap, allLocalBindings);
223
+ const refsByGroup = /* @__PURE__ */ new Map();
224
+ for (const prop of routeOptions.properties) {
225
+ if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) continue;
226
+ const key = prop.key.name;
227
+ if (key === "codeSplitGroupings") continue;
228
+ const groupIndex = findIndexForSplitNode(key);
229
+ const directRefs = collectModuleLevelRefsFromNode(
230
+ prop.value,
231
+ localModuleLevelBindings
232
+ );
233
+ const allRefs = new Set(directRefs);
234
+ expandTransitively(allRefs, depGraph);
235
+ for (const ref of allRefs) {
236
+ let groups = refsByGroup.get(ref);
237
+ if (!groups) {
238
+ groups = /* @__PURE__ */ new Set();
239
+ refsByGroup.set(ref, groups);
240
+ }
241
+ groups.add(groupIndex);
242
+ }
243
+ }
244
+ const shared = /* @__PURE__ */ new Set();
245
+ for (const [name, groups] of refsByGroup) {
246
+ if (groups.size >= 2) shared.add(name);
247
+ }
248
+ expandSharedDestructuredDeclarators(ast, refsByGroup, shared);
249
+ if (shared.size === 0) return shared;
250
+ expandDestructuredDeclarations(ast, shared);
251
+ removeBindingsDependingOnRoute(shared, fullDepGraph);
252
+ return shared;
253
+ }
254
+ function expandSharedDestructuredDeclarators(ast, refsByGroup, shared) {
255
+ for (const stmt of ast.program.body) {
256
+ const decl = t.isExportNamedDeclaration(stmt) && stmt.declaration ? stmt.declaration : stmt;
257
+ if (!t.isVariableDeclaration(decl)) continue;
258
+ for (const declarator of decl.declarations) {
259
+ if (!t.isObjectPattern(declarator.id) && !t.isArrayPattern(declarator.id))
260
+ continue;
261
+ const names = collectIdentifiersFromPattern(declarator.id);
262
+ const usedGroups = /* @__PURE__ */ new Set();
263
+ for (const name of names) {
264
+ const groups = refsByGroup.get(name);
265
+ if (!groups) continue;
266
+ for (const g of groups) usedGroups.add(g);
267
+ }
268
+ if (usedGroups.size >= 2) {
269
+ for (const name of names) {
270
+ shared.add(name);
271
+ }
272
+ }
273
+ }
274
+ }
275
+ }
276
+ function collectLocalBindingsFromStatement(node, bindings) {
277
+ const decl = t.isExportNamedDeclaration(node) && node.declaration ? node.declaration : node;
278
+ if (t.isVariableDeclaration(decl)) {
279
+ for (const declarator of decl.declarations) {
280
+ for (const name of collectIdentifiersFromPattern(declarator.id)) {
281
+ bindings.add(name);
282
+ }
283
+ }
284
+ } else if (t.isFunctionDeclaration(decl) && decl.id) {
285
+ bindings.add(decl.id.name);
286
+ } else if (t.isClassDeclaration(decl) && decl.id) {
287
+ bindings.add(decl.id.name);
288
+ }
289
+ }
290
+ function collectModuleLevelRefsFromNode(node, localModuleLevelBindings) {
291
+ const allIds = collectIdentifiersFromNode(node);
292
+ const refs = /* @__PURE__ */ new Set();
293
+ for (const name of allIds) {
294
+ if (localModuleLevelBindings.has(name)) refs.add(name);
295
+ }
296
+ return refs;
297
+ }
298
+ function expandTransitively(shared, depGraph) {
299
+ const queue = [...shared];
300
+ const visited = /* @__PURE__ */ new Set();
301
+ while (queue.length > 0) {
302
+ const name = queue.pop();
303
+ if (visited.has(name)) continue;
304
+ visited.add(name);
305
+ const deps = depGraph.get(name);
306
+ if (!deps) continue;
307
+ for (const dep of deps) {
308
+ if (!shared.has(dep)) {
309
+ shared.add(dep);
310
+ queue.push(dep);
311
+ }
312
+ }
313
+ }
314
+ }
315
+ function removeBindingsDependingOnRoute(shared, depGraph) {
316
+ const reverseGraph = /* @__PURE__ */ new Map();
317
+ for (const [name, deps] of depGraph) {
318
+ for (const dep of deps) {
319
+ let parents = reverseGraph.get(dep);
320
+ if (!parents) {
321
+ parents = /* @__PURE__ */ new Set();
322
+ reverseGraph.set(dep, parents);
323
+ }
324
+ parents.add(name);
325
+ }
326
+ }
327
+ const visited = /* @__PURE__ */ new Set();
328
+ const queue = ["Route"];
329
+ while (queue.length > 0) {
330
+ const cur = queue.pop();
331
+ if (visited.has(cur)) continue;
332
+ visited.add(cur);
333
+ const parents = reverseGraph.get(cur);
334
+ if (!parents) continue;
335
+ for (const parent of parents) {
336
+ if (!visited.has(parent)) queue.push(parent);
337
+ }
338
+ }
339
+ for (const name of [...shared]) {
340
+ if (visited.has(name)) {
341
+ shared.delete(name);
342
+ }
343
+ }
344
+ }
345
+ function expandDestructuredDeclarations(ast, shared) {
346
+ for (const stmt of ast.program.body) {
347
+ const decl = t.isExportNamedDeclaration(stmt) && stmt.declaration ? stmt.declaration : stmt;
348
+ if (!t.isVariableDeclaration(decl)) continue;
349
+ for (const declarator of decl.declarations) {
350
+ if (!t.isObjectPattern(declarator.id) && !t.isArrayPattern(declarator.id))
351
+ continue;
352
+ const names = collectIdentifiersFromPattern(declarator.id);
353
+ const hasShared = names.some((n) => shared.has(n));
354
+ if (hasShared) {
355
+ for (const n of names) {
356
+ shared.add(n);
357
+ }
358
+ }
359
+ }
360
+ }
361
+ }
362
+ function findExportedSharedBindings(ast, sharedBindings) {
363
+ const exported = /* @__PURE__ */ new Set();
364
+ for (const stmt of ast.program.body) {
365
+ if (!t.isExportNamedDeclaration(stmt) || !stmt.declaration) continue;
366
+ if (t.isVariableDeclaration(stmt.declaration)) {
367
+ for (const decl of stmt.declaration.declarations) {
368
+ for (const name of collectIdentifiersFromPattern(decl.id)) {
369
+ if (sharedBindings.has(name)) exported.add(name);
370
+ }
371
+ }
372
+ } else if (t.isFunctionDeclaration(stmt.declaration) && stmt.declaration.id) {
373
+ if (sharedBindings.has(stmt.declaration.id.name))
374
+ exported.add(stmt.declaration.id.name);
375
+ } else if (t.isClassDeclaration(stmt.declaration) && stmt.declaration.id) {
376
+ if (sharedBindings.has(stmt.declaration.id.name))
377
+ exported.add(stmt.declaration.id.name);
378
+ }
379
+ }
380
+ return exported;
381
+ }
382
+ function removeSharedDeclarations(ast, sharedBindings) {
383
+ ast.program.body = ast.program.body.filter((stmt) => {
384
+ const decl = t.isExportNamedDeclaration(stmt) && stmt.declaration ? stmt.declaration : stmt;
385
+ if (t.isVariableDeclaration(decl)) {
386
+ decl.declarations = decl.declarations.filter((declarator) => {
387
+ const names = collectIdentifiersFromPattern(declarator.id);
388
+ return !names.every((n) => sharedBindings.has(n));
389
+ });
390
+ if (decl.declarations.length === 0) return false;
391
+ } else if (t.isFunctionDeclaration(decl) && decl.id) {
392
+ if (sharedBindings.has(decl.id.name)) return false;
393
+ } else if (t.isClassDeclaration(decl) && decl.id) {
394
+ if (sharedBindings.has(decl.id.name)) return false;
395
+ }
396
+ return true;
397
+ });
398
+ }
97
399
  function compileCodeSplitReferenceRoute(opts) {
98
400
  const ast = parseAst(opts);
99
401
  const refIdents = findReferencedIdentifiers(ast);
@@ -110,6 +412,7 @@ function compileCodeSplitReferenceRoute(opts) {
110
412
  let createRouteFn;
111
413
  let modified = false;
112
414
  let hmrAdded = false;
415
+ let sharedExportedNames;
113
416
  babel.traverse(ast, {
114
417
  Program: {
115
418
  enter(programPath) {
@@ -305,6 +608,44 @@ function compileCodeSplitReferenceRoute(opts) {
305
608
  }
306
609
  });
307
610
  }
611
+ if (opts.sharedBindings && opts.sharedBindings.size > 0) {
612
+ sharedExportedNames = findExportedSharedBindings(
613
+ ast,
614
+ opts.sharedBindings
615
+ );
616
+ removeSharedDeclarations(ast, opts.sharedBindings);
617
+ const sharedModuleUrl = addSharedSearchParamToFilename(opts.filename);
618
+ const sharedImportSpecifiers = [...opts.sharedBindings].map(
619
+ (name) => t.importSpecifier(t.identifier(name), t.identifier(name))
620
+ );
621
+ const [sharedImportPath] = programPath.unshiftContainer(
622
+ "body",
623
+ t.importDeclaration(
624
+ sharedImportSpecifiers,
625
+ t.stringLiteral(sharedModuleUrl)
626
+ )
627
+ );
628
+ sharedImportPath.traverse({
629
+ Identifier(identPath) {
630
+ if (identPath.parentPath.isImportSpecifier() && identPath.key === "local") {
631
+ refIdents.add(identPath);
632
+ }
633
+ }
634
+ });
635
+ if (sharedExportedNames.size > 0) {
636
+ const reExportSpecifiers = [...sharedExportedNames].map(
637
+ (name) => t.exportSpecifier(t.identifier(name), t.identifier(name))
638
+ );
639
+ programPath.pushContainer(
640
+ "body",
641
+ t.exportNamedDeclaration(
642
+ null,
643
+ reExportSpecifiers,
644
+ t.stringLiteral(sharedModuleUrl)
645
+ )
646
+ );
647
+ }
648
+ }
308
649
  }
309
650
  }
310
651
  });
@@ -334,6 +675,9 @@ function compileCodeSplitReferenceRoute(opts) {
334
675
  function compileCodeSplitVirtualRoute(opts) {
335
676
  const ast = parseAst(opts);
336
677
  const refIdents = findReferencedIdentifiers(ast);
678
+ if (opts.sharedBindings && opts.sharedBindings.size > 0) {
679
+ removeSharedDeclarations(ast, opts.sharedBindings);
680
+ }
337
681
  const intendedSplitNodes = new Set(opts.splitTargets);
338
682
  const knownExportedIdents = /* @__PURE__ */ new Set();
339
683
  babel.traverse(ast, {
@@ -410,6 +754,10 @@ function compileCodeSplitVirtualRoute(opts) {
410
754
  }
411
755
  let splitNode = splitKey.node;
412
756
  const splitMeta = { ...splitKey.meta, shouldRemoveNode: true };
757
+ let originalIdentName;
758
+ if (t.isIdentifier(splitNode)) {
759
+ originalIdentName = splitNode.name;
760
+ }
413
761
  while (t.isIdentifier(splitNode)) {
414
762
  const binding = programPath.scope.getBinding(splitNode.name);
415
763
  splitNode = binding?.path.node;
@@ -447,6 +795,11 @@ function compileCodeSplitVirtualRoute(opts) {
447
795
  if (t.isIdentifier(splitNode.id)) {
448
796
  splitMeta.localExporterIdent = splitNode.id.name;
449
797
  splitMeta.shouldRemoveNode = false;
798
+ } else if (t.isObjectPattern(splitNode.id)) {
799
+ if (originalIdentName) {
800
+ splitMeta.localExporterIdent = originalIdentName;
801
+ }
802
+ splitMeta.shouldRemoveNode = false;
450
803
  } else {
451
804
  throw new Error(
452
805
  `Unexpected splitNode type ☝️: ${splitNode.type}`
@@ -532,13 +885,41 @@ function compileCodeSplitVirtualRoute(opts) {
532
885
  ExportNamedDeclaration(path) {
533
886
  if (path.node.declaration) {
534
887
  if (t.isVariableDeclaration(path.node.declaration)) {
888
+ const specifiers = path.node.declaration.declarations.flatMap(
889
+ (decl) => {
890
+ if (t.isIdentifier(decl.id)) {
891
+ return [
892
+ t.importSpecifier(
893
+ t.identifier(decl.id.name),
894
+ t.identifier(decl.id.name)
895
+ )
896
+ ];
897
+ }
898
+ if (t.isObjectPattern(decl.id)) {
899
+ return collectIdentifiersFromPattern(decl.id).map(
900
+ (name) => t.importSpecifier(
901
+ t.identifier(name),
902
+ t.identifier(name)
903
+ )
904
+ );
905
+ }
906
+ if (t.isArrayPattern(decl.id)) {
907
+ return collectIdentifiersFromPattern(decl.id).map(
908
+ (name) => t.importSpecifier(
909
+ t.identifier(name),
910
+ t.identifier(name)
911
+ )
912
+ );
913
+ }
914
+ return [];
915
+ }
916
+ );
917
+ if (specifiers.length === 0) {
918
+ path.remove();
919
+ return;
920
+ }
535
921
  const importDecl = t.importDeclaration(
536
- path.node.declaration.declarations.map(
537
- (decl) => t.importSpecifier(
538
- t.identifier(decl.id.name),
539
- t.identifier(decl.id.name)
540
- )
541
- ),
922
+ specifiers,
542
923
  t.stringLiteral(
543
924
  removeSplitSearchParamFromFilename(opts.filename)
544
925
  )
@@ -555,10 +936,121 @@ function compileCodeSplitVirtualRoute(opts) {
555
936
  }
556
937
  }
557
938
  });
939
+ if (opts.sharedBindings && opts.sharedBindings.size > 0) {
940
+ const sharedImportSpecifiers = [...opts.sharedBindings].map(
941
+ (name) => t.importSpecifier(t.identifier(name), t.identifier(name))
942
+ );
943
+ const sharedModuleUrl = addSharedSearchParamToFilename(
944
+ removeSplitSearchParamFromFilename(opts.filename)
945
+ );
946
+ const [sharedImportPath] = programPath.unshiftContainer(
947
+ "body",
948
+ t.importDeclaration(
949
+ sharedImportSpecifiers,
950
+ t.stringLiteral(sharedModuleUrl)
951
+ )
952
+ );
953
+ sharedImportPath.traverse({
954
+ Identifier(identPath) {
955
+ if (identPath.parentPath.isImportSpecifier() && identPath.key === "local") {
956
+ refIdents.add(identPath);
957
+ }
958
+ }
959
+ });
960
+ }
961
+ }
962
+ }
963
+ });
964
+ deadCodeElimination(ast, refIdents);
965
+ {
966
+ const locallyBound = /* @__PURE__ */ new Set();
967
+ for (const stmt of ast.program.body) {
968
+ collectLocalBindingsFromStatement(stmt, locallyBound);
969
+ }
970
+ ast.program.body = ast.program.body.filter((stmt) => {
971
+ if (!t.isExpressionStatement(stmt)) return true;
972
+ const refs = collectIdentifiersFromNode(stmt);
973
+ return [...refs].some((name) => locallyBound.has(name));
974
+ });
975
+ }
976
+ if (ast.program.body.length === 0) {
977
+ ast.program.directives = [];
978
+ }
979
+ return generateFromAst(ast, {
980
+ sourceMaps: true,
981
+ sourceFileName: opts.filename,
982
+ filename: opts.filename
983
+ });
984
+ }
985
+ function compileCodeSplitSharedRoute(opts) {
986
+ const ast = parseAst(opts);
987
+ const refIdents = findReferencedIdentifiers(ast);
988
+ const localBindings = /* @__PURE__ */ new Set();
989
+ for (const node of ast.program.body) {
990
+ collectLocalBindingsFromStatement(node, localBindings);
991
+ }
992
+ localBindings.delete("Route");
993
+ const declMap = buildDeclarationMap(ast);
994
+ const depGraph = buildDependencyGraph(declMap, localBindings);
995
+ const keepBindings = new Set(opts.sharedBindings);
996
+ keepBindings.delete("Route");
997
+ expandTransitively(keepBindings, depGraph);
998
+ ast.program.body = ast.program.body.filter((stmt) => {
999
+ if (t.isImportDeclaration(stmt)) return true;
1000
+ const decl = t.isExportNamedDeclaration(stmt) && stmt.declaration ? stmt.declaration : stmt;
1001
+ if (t.isVariableDeclaration(decl)) {
1002
+ decl.declarations = decl.declarations.filter((declarator) => {
1003
+ const names = collectIdentifiersFromPattern(declarator.id);
1004
+ return names.some((n) => keepBindings.has(n));
1005
+ });
1006
+ if (decl.declarations.length === 0) return false;
1007
+ if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
1008
+ return true;
558
1009
  }
1010
+ return true;
1011
+ } else if (t.isFunctionDeclaration(decl) && decl.id) {
1012
+ return keepBindings.has(decl.id.name);
1013
+ } else if (t.isClassDeclaration(decl) && decl.id) {
1014
+ return keepBindings.has(decl.id.name);
1015
+ }
1016
+ return false;
1017
+ });
1018
+ ast.program.body = ast.program.body.map((stmt) => {
1019
+ if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
1020
+ return stmt.declaration;
559
1021
  }
1022
+ return stmt;
560
1023
  });
1024
+ const exportNames = [...opts.sharedBindings].sort(
1025
+ (a, b) => a.localeCompare(b)
1026
+ );
1027
+ const exportSpecifiers = exportNames.map(
1028
+ (name) => t.exportSpecifier(t.identifier(name), t.identifier(name))
1029
+ );
1030
+ if (exportSpecifiers.length > 0) {
1031
+ const exportDecl = t.exportNamedDeclaration(null, exportSpecifiers);
1032
+ ast.program.body.push(exportDecl);
1033
+ babel.traverse(ast, {
1034
+ Program(programPath) {
1035
+ const bodyPaths = programPath.get("body");
1036
+ const last = bodyPaths[bodyPaths.length - 1];
1037
+ if (last && last.isExportNamedDeclaration()) {
1038
+ last.traverse({
1039
+ Identifier(identPath) {
1040
+ if (identPath.parentPath.isExportSpecifier() && identPath.key === "local") {
1041
+ refIdents.add(identPath);
1042
+ }
1043
+ }
1044
+ });
1045
+ }
1046
+ programPath.stop();
1047
+ }
1048
+ });
1049
+ }
561
1050
  deadCodeElimination(ast, refIdents);
1051
+ if (ast.program.body.length === 0) {
1052
+ ast.program.directives = [];
1053
+ }
562
1054
  return generateFromAst(ast, {
563
1055
  sourceMaps: true,
564
1056
  sourceFileName: opts.filename,
@@ -658,6 +1150,37 @@ function getImportSpecifierAndPathFromLocalName(programPath, name) {
658
1150
  });
659
1151
  return { specifier, path };
660
1152
  }
1153
+ function collectIdentifiersFromPattern(node) {
1154
+ if (!node) {
1155
+ return [];
1156
+ }
1157
+ if (t.isIdentifier(node)) {
1158
+ return [node.name];
1159
+ }
1160
+ if (t.isAssignmentPattern(node)) {
1161
+ return collectIdentifiersFromPattern(node.left);
1162
+ }
1163
+ if (t.isRestElement(node)) {
1164
+ return collectIdentifiersFromPattern(node.argument);
1165
+ }
1166
+ if (t.isObjectPattern(node)) {
1167
+ return node.properties.flatMap((prop) => {
1168
+ if (t.isObjectProperty(prop)) {
1169
+ return collectIdentifiersFromPattern(prop.value);
1170
+ }
1171
+ if (t.isRestElement(prop)) {
1172
+ return collectIdentifiersFromPattern(prop.argument);
1173
+ }
1174
+ return [];
1175
+ });
1176
+ }
1177
+ if (t.isArrayPattern(node)) {
1178
+ return node.elements.flatMap(
1179
+ (element) => collectIdentifiersFromPattern(element)
1180
+ );
1181
+ }
1182
+ return [];
1183
+ }
661
1184
  function resolveIdentifier(path, node) {
662
1185
  if (t.isIdentifier(node)) {
663
1186
  const binding = path.scope.getBinding(node.name);
@@ -676,6 +1199,25 @@ function resolveIdentifier(path, node) {
676
1199
  function removeIdentifierLiteral(path, node) {
677
1200
  const binding = path.scope.getBinding(node.name);
678
1201
  if (binding) {
1202
+ if (t.isVariableDeclarator(binding.path.node) && t.isObjectPattern(binding.path.node.id)) {
1203
+ const objectPattern = binding.path.node.id;
1204
+ objectPattern.properties = objectPattern.properties.filter((prop) => {
1205
+ if (!t.isObjectProperty(prop)) {
1206
+ return true;
1207
+ }
1208
+ if (t.isIdentifier(prop.value) && prop.value.name === node.name) {
1209
+ return false;
1210
+ }
1211
+ if (t.isAssignmentPattern(prop.value) && t.isIdentifier(prop.value.left) && prop.value.left.name === node.name) {
1212
+ return false;
1213
+ }
1214
+ return true;
1215
+ });
1216
+ if (objectPattern.properties.length === 0) {
1217
+ binding.path.remove();
1218
+ }
1219
+ return;
1220
+ }
679
1221
  binding.path.remove();
680
1222
  }
681
1223
  }
@@ -691,6 +1233,11 @@ function hasExport(ast, node) {
691
1233
  if (decl.id.name === node.name) {
692
1234
  found = true;
693
1235
  }
1236
+ } else if (t.isObjectPattern(decl.id) || t.isArrayPattern(decl.id)) {
1237
+ const names = collectIdentifiersFromPattern(decl.id);
1238
+ if (names.includes(node.name)) {
1239
+ found = true;
1240
+ }
694
1241
  }
695
1242
  }
696
1243
  });
@@ -734,6 +1281,12 @@ function removeExports(ast, node) {
734
1281
  path.remove();
735
1282
  removed = true;
736
1283
  }
1284
+ } else if (t.isObjectPattern(decl.id) || t.isArrayPattern(decl.id)) {
1285
+ const names = collectIdentifiersFromPattern(decl.id);
1286
+ if (names.includes(node.name)) {
1287
+ path.remove();
1288
+ removed = true;
1289
+ }
737
1290
  }
738
1291
  }
739
1292
  });
@@ -766,8 +1319,20 @@ function removeExports(ast, node) {
766
1319
  return removed;
767
1320
  }
768
1321
  export {
1322
+ addSharedSearchParamToFilename,
1323
+ buildDeclarationMap,
1324
+ buildDependencyGraph,
1325
+ collectIdentifiersFromNode,
1326
+ collectLocalBindingsFromStatement,
1327
+ collectModuleLevelRefsFromNode,
769
1328
  compileCodeSplitReferenceRoute,
1329
+ compileCodeSplitSharedRoute,
770
1330
  compileCodeSplitVirtualRoute,
771
- detectCodeSplitGroupingsFromRoute
1331
+ computeSharedBindings,
1332
+ detectCodeSplitGroupingsFromRoute,
1333
+ expandDestructuredDeclarations,
1334
+ expandSharedDestructuredDeclarators,
1335
+ expandTransitively,
1336
+ removeBindingsDependingOnRoute
772
1337
  };
773
1338
  //# sourceMappingURL=compilers.js.map