@barefootjs/vite 0.31.3 → 0.31.4
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/index.js +171 -145
- package/package.json +6 -6
- package/src/__tests__/dynamic-import-rewrite.test.ts +92 -0
package/dist/index.js
CHANGED
|
@@ -1655,6 +1655,24 @@ function templatePartsToJsExpr(parts, opts) {
|
|
|
1655
1655
|
return result;
|
|
1656
1656
|
}
|
|
1657
1657
|
|
|
1658
|
+
// ../jsx/src/identifier-pattern.ts
|
|
1659
|
+
function withUnicodeFlag(flags) {
|
|
1660
|
+
return flags.includes("u") ? flags : `${flags}u`;
|
|
1661
|
+
}
|
|
1662
|
+
function escapeIdentifierForRegex(name) {
|
|
1663
|
+
return name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1664
|
+
}
|
|
1665
|
+
var ID_BOUNDARY_BEFORE = "(?<![\\p{ID_Continue}$])";
|
|
1666
|
+
var ID_BOUNDARY_AFTER = "(?![\\p{ID_Continue}$])";
|
|
1667
|
+
function identifierPattern(name, flags = "") {
|
|
1668
|
+
const esc = escapeIdentifierForRegex(name);
|
|
1669
|
+
return new RegExp(`${ID_BOUNDARY_BEFORE}${esc}${ID_BOUNDARY_AFTER}`, withUnicodeFlag(flags));
|
|
1670
|
+
}
|
|
1671
|
+
function identifierCallPattern(name, flags = "") {
|
|
1672
|
+
const esc = escapeIdentifierForRegex(name);
|
|
1673
|
+
return new RegExp(`${ID_BOUNDARY_BEFORE}${esc}\\s*\\(`, withUnicodeFlag(flags));
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1658
1676
|
// ../jsx/src/scanner/js-scanner.ts
|
|
1659
1677
|
import ts2 from "typescript";
|
|
1660
1678
|
function* iterateJsTokens(text, start = 0, end = text.length) {
|
|
@@ -2227,9 +2245,6 @@ function inferDefaultValue(type) {
|
|
|
2227
2245
|
return "{}";
|
|
2228
2246
|
return "undefined";
|
|
2229
2247
|
}
|
|
2230
|
-
function escapeRegExp(s) {
|
|
2231
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2232
|
-
}
|
|
2233
2248
|
function freeIdsFromRefs(refs) {
|
|
2234
2249
|
const out = new Set;
|
|
2235
2250
|
if (!refs)
|
|
@@ -2357,16 +2372,16 @@ function wrapLoopParamAsAccessor(expr, paramName, bindings) {
|
|
|
2357
2372
|
if (bindings && bindings.length > 0) {
|
|
2358
2373
|
return rewriteLoopBindingRefs(expr, bindings, "__bfItem()");
|
|
2359
2374
|
}
|
|
2360
|
-
const re = new RegExp(
|
|
2361
|
-
return replaceInExprContexts(expr, re, `${paramName}()`);
|
|
2375
|
+
const re = new RegExp(`${ID_BOUNDARY_BEFORE}${escapeIdentifierForRegex(paramName)}(?!\\s*\\()(?!-)${ID_BOUNDARY_AFTER}`, "gu");
|
|
2376
|
+
return replaceInExprContexts(expr, re, () => `${paramName}()`);
|
|
2362
2377
|
}
|
|
2363
2378
|
function rewriteLoopBindingRefs(expr, bindings, accessor) {
|
|
2364
2379
|
const byName = new Map;
|
|
2365
2380
|
for (const b of bindings)
|
|
2366
2381
|
byName.set(b.name, b);
|
|
2367
2382
|
const preprocessed = expandShorthandBindings(expr, new Set(byName.keys()));
|
|
2368
|
-
const alt = bindings.map((b) =>
|
|
2369
|
-
const re = new RegExp(
|
|
2383
|
+
const alt = bindings.map((b) => escapeIdentifierForRegex(b.name)).join("|");
|
|
2384
|
+
const re = new RegExp(`${ID_BOUNDARY_BEFORE}(${alt})${ID_BOUNDARY_AFTER}`, "gu");
|
|
2370
2385
|
return replaceInExprContexts(preprocessed, re, (_m, name) => renderLoopBindingAccess(byName.get(name), accessor));
|
|
2371
2386
|
}
|
|
2372
2387
|
function expandShorthandBindings(expr, bindingNames) {
|
|
@@ -2633,7 +2648,7 @@ function stopAt(...kinds) {
|
|
|
2633
2648
|
|
|
2634
2649
|
// ../jsx/src/ir-to-client-js/csr-substitute.ts
|
|
2635
2650
|
import ts4 from "typescript";
|
|
2636
|
-
function csrSubstitute(value, env) {
|
|
2651
|
+
function csrSubstitute(value, env, enclosingScope) {
|
|
2637
2652
|
if (!value || value.trim().length === 0) {
|
|
2638
2653
|
return { rewritten: value, freeIdentifiers: new Set };
|
|
2639
2654
|
}
|
|
@@ -2641,7 +2656,7 @@ function csrSubstitute(value, env) {
|
|
|
2641
2656
|
let current = value;
|
|
2642
2657
|
let lastFreeIdentifiers = new Set;
|
|
2643
2658
|
for (let i = 0;i < maxIter; i++) {
|
|
2644
|
-
const step = csrSubstituteOnce(current, env);
|
|
2659
|
+
const step = csrSubstituteOnce(current, env, enclosingScope);
|
|
2645
2660
|
lastFreeIdentifiers = step.freeIdentifiers;
|
|
2646
2661
|
if (step.rewritten === current)
|
|
2647
2662
|
break;
|
|
@@ -2649,7 +2664,7 @@ function csrSubstitute(value, env) {
|
|
|
2649
2664
|
}
|
|
2650
2665
|
return { rewritten: current, freeIdentifiers: lastFreeIdentifiers };
|
|
2651
2666
|
}
|
|
2652
|
-
function csrSubstituteOnce(value, env) {
|
|
2667
|
+
function csrSubstituteOnce(value, env, enclosingScope) {
|
|
2653
2668
|
if (!value || value.trim().length === 0) {
|
|
2654
2669
|
return { rewritten: value, freeIdentifiers: new Set };
|
|
2655
2670
|
}
|
|
@@ -2667,7 +2682,7 @@ function csrSubstituteOnce(value, env) {
|
|
|
2667
2682
|
if (boundStack[i].has(name))
|
|
2668
2683
|
return true;
|
|
2669
2684
|
}
|
|
2670
|
-
return false;
|
|
2685
|
+
return enclosingScope?.isBound(name) ?? false;
|
|
2671
2686
|
};
|
|
2672
2687
|
const recordSubstitution = (start, end, sub) => {
|
|
2673
2688
|
splices.push({ start: start - OFFSET, end: end - OFFSET, text: `(${sub.replacement})` });
|
|
@@ -2852,6 +2867,83 @@ function derivesScopeFromSlot(comp) {
|
|
|
2852
2867
|
return comp.slotId != null && comp.loopItemRoot !== true;
|
|
2853
2868
|
}
|
|
2854
2869
|
|
|
2870
|
+
// ../jsx/src/scope/binding-scope.ts
|
|
2871
|
+
class BindingScope {
|
|
2872
|
+
frames;
|
|
2873
|
+
static EMPTY = new BindingScope([]);
|
|
2874
|
+
constructor(frames) {
|
|
2875
|
+
this.frames = frames;
|
|
2876
|
+
}
|
|
2877
|
+
enterLoopRow(loop) {
|
|
2878
|
+
const bindings = new Map;
|
|
2879
|
+
if (loop.paramBindings && loop.paramBindings.length > 0) {
|
|
2880
|
+
for (const b of loop.paramBindings)
|
|
2881
|
+
bindings.set(b.name, { source: "destructure" });
|
|
2882
|
+
} else {
|
|
2883
|
+
bindings.set(loop.param, { source: "item" });
|
|
2884
|
+
}
|
|
2885
|
+
if (loop.index != null)
|
|
2886
|
+
bindings.set(loop.index, { source: "index" });
|
|
2887
|
+
for (const name of loop.preamble?.declaredNames ?? [])
|
|
2888
|
+
bindings.set(name, { source: "preamble" });
|
|
2889
|
+
const frame = { kind: "loop-row", bindings };
|
|
2890
|
+
return new BindingScope([frame, ...this.frames]);
|
|
2891
|
+
}
|
|
2892
|
+
enterCallback(params) {
|
|
2893
|
+
const bindings = new Map;
|
|
2894
|
+
for (const name of params)
|
|
2895
|
+
bindings.set(name, { source: "param" });
|
|
2896
|
+
const frame = { kind: "callback", bindings };
|
|
2897
|
+
return new BindingScope([frame, ...this.frames]);
|
|
2898
|
+
}
|
|
2899
|
+
isBound(name) {
|
|
2900
|
+
for (const frame of this.frames) {
|
|
2901
|
+
if (frame.bindings.has(name))
|
|
2902
|
+
return true;
|
|
2903
|
+
}
|
|
2904
|
+
return false;
|
|
2905
|
+
}
|
|
2906
|
+
lookup(name) {
|
|
2907
|
+
for (let depth = 0;depth < this.frames.length; depth++) {
|
|
2908
|
+
const frame = this.frames[depth];
|
|
2909
|
+
const binding = frame.bindings.get(name);
|
|
2910
|
+
if (binding)
|
|
2911
|
+
return { depth, frame, binding };
|
|
2912
|
+
}
|
|
2913
|
+
return null;
|
|
2914
|
+
}
|
|
2915
|
+
boundNames() {
|
|
2916
|
+
if (this.boundNamesCache)
|
|
2917
|
+
return this.boundNamesCache;
|
|
2918
|
+
const names = new Set;
|
|
2919
|
+
for (const frame of this.frames) {
|
|
2920
|
+
for (const name of frame.bindings.keys())
|
|
2921
|
+
names.add(name);
|
|
2922
|
+
}
|
|
2923
|
+
this.boundNamesCache = names;
|
|
2924
|
+
return names;
|
|
2925
|
+
}
|
|
2926
|
+
boundNamesCache;
|
|
2927
|
+
valueBoundNamesCache;
|
|
2928
|
+
valueBoundNames() {
|
|
2929
|
+
if (this.valueBoundNamesCache)
|
|
2930
|
+
return this.valueBoundNamesCache;
|
|
2931
|
+
const names = new Set;
|
|
2932
|
+
for (const frame of this.frames) {
|
|
2933
|
+
for (const [name, binding] of frame.bindings) {
|
|
2934
|
+
if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
|
|
2935
|
+
names.add(name);
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
this.valueBoundNamesCache = names;
|
|
2940
|
+
return names;
|
|
2941
|
+
}
|
|
2942
|
+
asShadowPredicate() {
|
|
2943
|
+
return (name) => this.isBound(name);
|
|
2944
|
+
}
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2855
2947
|
// ../jsx/src/ir-to-client-js/html-template.ts
|
|
2856
2948
|
function createStringProtector() {
|
|
2857
2949
|
const strings = [];
|
|
@@ -4077,7 +4169,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4077
4169
|
const source = templateExpr ?? expr;
|
|
4078
4170
|
if (!source)
|
|
4079
4171
|
return source;
|
|
4080
|
-
const { rewritten, freeIdentifiers: freeIdentifiers2 } = csrSubstitute(source, env);
|
|
4172
|
+
const { rewritten, freeIdentifiers: freeIdentifiers2 } = csrSubstitute(source, env, opts.scope);
|
|
4081
4173
|
if (unsafeLocalNames && unsafeLocalNames.size > 0 && setIntersects(freeIdentifiers2, unsafeLocalNames)) {
|
|
4082
4174
|
return UNSAFE_TEMPLATE_EXPR;
|
|
4083
4175
|
}
|
|
@@ -4219,15 +4311,8 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4219
4311
|
return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
|
|
4220
4312
|
}
|
|
4221
4313
|
case "loop": {
|
|
4222
|
-
const
|
|
4223
|
-
|
|
4224
|
-
for (const b of node.paramBindings)
|
|
4225
|
-
boundHere.add(b.name);
|
|
4226
|
-
} else if (!node.param.startsWith("[") && !node.param.startsWith("{")) {
|
|
4227
|
-
boundHere.add(node.param);
|
|
4228
|
-
}
|
|
4229
|
-
if (node.index)
|
|
4230
|
-
boundHere.add(node.index);
|
|
4314
|
+
const childScope = (opts.scope ?? BindingScope.EMPTY).enterLoopRow(node);
|
|
4315
|
+
const boundHere = childScope.boundNames();
|
|
4231
4316
|
const childEnv = {
|
|
4232
4317
|
...env,
|
|
4233
4318
|
substitutions: new Map([...env.substitutions].filter(([name]) => !boundHere.has(name)))
|
|
@@ -4236,7 +4321,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4236
4321
|
...opts,
|
|
4237
4322
|
loopDepth: loopDepth + 1,
|
|
4238
4323
|
inHoistedChildren: false,
|
|
4239
|
-
|
|
4324
|
+
scope: childScope,
|
|
4240
4325
|
csrEnv: childEnv
|
|
4241
4326
|
});
|
|
4242
4327
|
let childTemplate = node.children.map(recurseInLoopBody).join("");
|
|
@@ -8754,7 +8839,7 @@ function findReachableNames(primaryRefs, declarations) {
|
|
|
8754
8839
|
const reachable = new Set;
|
|
8755
8840
|
const queue = [];
|
|
8756
8841
|
for (const name of allNames) {
|
|
8757
|
-
if (
|
|
8842
|
+
if (identifierPattern(name).test(primaryRefs)) {
|
|
8758
8843
|
reachable.add(name);
|
|
8759
8844
|
queue.push(name);
|
|
8760
8845
|
}
|
|
@@ -8763,7 +8848,7 @@ function findReachableNames(primaryRefs, declarations) {
|
|
|
8763
8848
|
const current = queue.shift();
|
|
8764
8849
|
const body = bodyMap.get(current) || "";
|
|
8765
8850
|
for (const name of allNames) {
|
|
8766
|
-
if (!reachable.has(name) &&
|
|
8851
|
+
if (!reachable.has(name) && identifierPattern(name).test(body)) {
|
|
8767
8852
|
reachable.add(name);
|
|
8768
8853
|
queue.push(name);
|
|
8769
8854
|
}
|
|
@@ -9429,83 +9514,6 @@ var toLocaleDatePlugin = {
|
|
|
9429
9514
|
}
|
|
9430
9515
|
};
|
|
9431
9516
|
|
|
9432
|
-
// ../jsx/src/scope/binding-scope.ts
|
|
9433
|
-
class BindingScope {
|
|
9434
|
-
frames;
|
|
9435
|
-
static EMPTY = new BindingScope([]);
|
|
9436
|
-
constructor(frames) {
|
|
9437
|
-
this.frames = frames;
|
|
9438
|
-
}
|
|
9439
|
-
enterLoopRow(loop) {
|
|
9440
|
-
const bindings = new Map;
|
|
9441
|
-
if (loop.paramBindings && loop.paramBindings.length > 0) {
|
|
9442
|
-
for (const b of loop.paramBindings)
|
|
9443
|
-
bindings.set(b.name, { source: "destructure" });
|
|
9444
|
-
} else {
|
|
9445
|
-
bindings.set(loop.param, { source: "item" });
|
|
9446
|
-
}
|
|
9447
|
-
if (loop.index != null)
|
|
9448
|
-
bindings.set(loop.index, { source: "index" });
|
|
9449
|
-
for (const name of loop.preamble?.declaredNames ?? [])
|
|
9450
|
-
bindings.set(name, { source: "preamble" });
|
|
9451
|
-
const frame = { kind: "loop-row", bindings };
|
|
9452
|
-
return new BindingScope([frame, ...this.frames]);
|
|
9453
|
-
}
|
|
9454
|
-
enterCallback(params) {
|
|
9455
|
-
const bindings = new Map;
|
|
9456
|
-
for (const name of params)
|
|
9457
|
-
bindings.set(name, { source: "param" });
|
|
9458
|
-
const frame = { kind: "callback", bindings };
|
|
9459
|
-
return new BindingScope([frame, ...this.frames]);
|
|
9460
|
-
}
|
|
9461
|
-
isBound(name) {
|
|
9462
|
-
for (const frame of this.frames) {
|
|
9463
|
-
if (frame.bindings.has(name))
|
|
9464
|
-
return true;
|
|
9465
|
-
}
|
|
9466
|
-
return false;
|
|
9467
|
-
}
|
|
9468
|
-
lookup(name) {
|
|
9469
|
-
for (let depth = 0;depth < this.frames.length; depth++) {
|
|
9470
|
-
const frame = this.frames[depth];
|
|
9471
|
-
const binding = frame.bindings.get(name);
|
|
9472
|
-
if (binding)
|
|
9473
|
-
return { depth, frame, binding };
|
|
9474
|
-
}
|
|
9475
|
-
return null;
|
|
9476
|
-
}
|
|
9477
|
-
boundNames() {
|
|
9478
|
-
if (this.boundNamesCache)
|
|
9479
|
-
return this.boundNamesCache;
|
|
9480
|
-
const names = new Set;
|
|
9481
|
-
for (const frame of this.frames) {
|
|
9482
|
-
for (const name of frame.bindings.keys())
|
|
9483
|
-
names.add(name);
|
|
9484
|
-
}
|
|
9485
|
-
this.boundNamesCache = names;
|
|
9486
|
-
return names;
|
|
9487
|
-
}
|
|
9488
|
-
boundNamesCache;
|
|
9489
|
-
valueBoundNamesCache;
|
|
9490
|
-
valueBoundNames() {
|
|
9491
|
-
if (this.valueBoundNamesCache)
|
|
9492
|
-
return this.valueBoundNamesCache;
|
|
9493
|
-
const names = new Set;
|
|
9494
|
-
for (const frame of this.frames) {
|
|
9495
|
-
for (const [name, binding] of frame.bindings) {
|
|
9496
|
-
if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
|
|
9497
|
-
names.add(name);
|
|
9498
|
-
}
|
|
9499
|
-
}
|
|
9500
|
-
}
|
|
9501
|
-
this.valueBoundNamesCache = names;
|
|
9502
|
-
return names;
|
|
9503
|
-
}
|
|
9504
|
-
asShadowPredicate() {
|
|
9505
|
-
return (name) => this.isBound(name);
|
|
9506
|
-
}
|
|
9507
|
-
}
|
|
9508
|
-
|
|
9509
9517
|
// ../jsx/src/jsx-to-ir.ts
|
|
9510
9518
|
var CLIENT_DIRECTIVE_INTERIOR_RE2 = /^\s*@client\s*$/;
|
|
9511
9519
|
var BLOCK_COMMENT_RE2 = /\/\*([\s\S]*?)\*\//g;
|
|
@@ -9769,17 +9777,17 @@ function createTransformContext(analyzer) {
|
|
|
9769
9777
|
patterns: {
|
|
9770
9778
|
signals: analyzer.signals.map((s) => ({
|
|
9771
9779
|
getter: s.getter,
|
|
9772
|
-
pattern:
|
|
9780
|
+
pattern: identifierCallPattern(s.getter)
|
|
9773
9781
|
})),
|
|
9774
9782
|
memos: analyzer.memos.map((m) => ({
|
|
9775
9783
|
name: m.name,
|
|
9776
|
-
pattern:
|
|
9784
|
+
pattern: identifierCallPattern(m.name)
|
|
9777
9785
|
})),
|
|
9778
|
-
props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern:
|
|
9786
|
+
props: analyzer.propsParams.filter((p) => p.name !== "children").map((p) => ({ name: p.name, pattern: identifierPattern(p.name) })),
|
|
9779
9787
|
constants: analyzer.localConstants.map((c) => ({
|
|
9780
9788
|
name: c.name,
|
|
9781
9789
|
value: c.value,
|
|
9782
|
-
pattern:
|
|
9790
|
+
pattern: identifierPattern(c.name)
|
|
9783
9791
|
}))
|
|
9784
9792
|
},
|
|
9785
9793
|
getJS(node) {
|
|
@@ -10551,7 +10559,7 @@ function transformExpressionInner(expr, ctx, node, isClientOnly) {
|
|
|
10551
10559
|
};
|
|
10552
10560
|
const reactive = isReactiveExpression(exprText, ctx, expr) || isReactiveOrigin(origin);
|
|
10553
10561
|
const scopeValueNames = ctx.scope.valueBoundNames();
|
|
10554
|
-
const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) =>
|
|
10562
|
+
const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) => identifierPattern(p).test(exprText));
|
|
10555
10563
|
const callsReactive = exprCallsReactiveGetters(expr, ctx);
|
|
10556
10564
|
const hasCalls = exprHasFunctionCalls(expr);
|
|
10557
10565
|
const needsSlot = reactive || isClientOnly || refsLoopParam || callsReactive || hasCalls;
|
|
@@ -10586,7 +10594,7 @@ function transformJsxFunctionCall(callExpr, jsxFunc, ctx, _isClientOnly) {
|
|
|
10586
10594
|
const substitutedGetJS = (node) => {
|
|
10587
10595
|
let text = baseGetJS(node);
|
|
10588
10596
|
for (const [paramName, argExpr] of substitutions) {
|
|
10589
|
-
text = text.replace(
|
|
10597
|
+
text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
|
|
10590
10598
|
}
|
|
10591
10599
|
return text;
|
|
10592
10600
|
};
|
|
@@ -10628,7 +10636,7 @@ function transformMultiReturnJsxFunctionCall(callExpr, info, ctx) {
|
|
|
10628
10636
|
const substitutedGetJS = (node) => {
|
|
10629
10637
|
let text = baseGetJS(node);
|
|
10630
10638
|
for (const [paramName, argExpr] of substitutions) {
|
|
10631
|
-
text = text.replace(
|
|
10639
|
+
text = text.replace(identifierPattern(paramName, "g"), () => argExpr);
|
|
10632
10640
|
}
|
|
10633
10641
|
return text;
|
|
10634
10642
|
};
|
|
@@ -13173,7 +13181,7 @@ function referencesLoopParam(expr, ctx) {
|
|
|
13173
13181
|
if (boundNames.size === 0)
|
|
13174
13182
|
return false;
|
|
13175
13183
|
for (const p of boundNames) {
|
|
13176
|
-
if (
|
|
13184
|
+
if (identifierPattern(p).test(expr))
|
|
13177
13185
|
return true;
|
|
13178
13186
|
}
|
|
13179
13187
|
return false;
|
|
@@ -13255,7 +13263,7 @@ function hasReactiveAttributes(attrs, ctx) {
|
|
|
13255
13263
|
const scopeValueNames = ctx.scope.valueBoundNames();
|
|
13256
13264
|
if (scopeValueNames.size > 0) {
|
|
13257
13265
|
for (const p of scopeValueNames) {
|
|
13258
|
-
if (
|
|
13266
|
+
if (identifierPattern(p).test(valueToCheck))
|
|
13259
13267
|
return true;
|
|
13260
13268
|
}
|
|
13261
13269
|
}
|
|
@@ -13461,18 +13469,22 @@ function buildIfStatementChain(analyzer, ctx, opts) {
|
|
|
13461
13469
|
}
|
|
13462
13470
|
|
|
13463
13471
|
// ../jsx/src/ir-to-client-js/prop-handling.ts
|
|
13464
|
-
function expandDynamicPropValue(value, ctx) {
|
|
13472
|
+
function expandDynamicPropValue(value, ctx, scope) {
|
|
13465
13473
|
const trimmedValue = value.trim();
|
|
13474
|
+
if (scope?.isBound(trimmedValue))
|
|
13475
|
+
return value;
|
|
13466
13476
|
const constant = ctx.localConstants.find((c) => c.name === trimmedValue);
|
|
13467
13477
|
if (constant && constant.value) {
|
|
13468
13478
|
return constant.value;
|
|
13469
13479
|
}
|
|
13470
13480
|
return value;
|
|
13471
13481
|
}
|
|
13472
|
-
function expandConstantForReactivity(expr, ctx, originalFreeIds) {
|
|
13482
|
+
function expandConstantForReactivity(expr, ctx, originalFreeIds, scope) {
|
|
13473
13483
|
if (ctx.propsObjectName)
|
|
13474
13484
|
return { expr, freeIds: originalFreeIds };
|
|
13475
13485
|
const trimmedValue = expr.trim();
|
|
13486
|
+
if (scope?.isBound(trimmedValue))
|
|
13487
|
+
return { expr, freeIds: originalFreeIds };
|
|
13476
13488
|
const constant = ctx.localConstants.find((c) => c.name === trimmedValue);
|
|
13477
13489
|
if (constant && constant.value) {
|
|
13478
13490
|
return { expr: constant.value, freeIds: constant.freeIdentifiers };
|
|
@@ -13508,6 +13520,16 @@ function getControlledPropName(signal, propsParams, propsObjectName = null) {
|
|
|
13508
13520
|
}
|
|
13509
13521
|
|
|
13510
13522
|
// ../jsx/src/ir-to-client-js/reactivity.ts
|
|
13523
|
+
function buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex) {
|
|
13524
|
+
if (!loopParam)
|
|
13525
|
+
return;
|
|
13526
|
+
return BindingScope.EMPTY.enterLoopRow({
|
|
13527
|
+
param: loopParam,
|
|
13528
|
+
paramBindings: loopParamBindings,
|
|
13529
|
+
index: loopIndex,
|
|
13530
|
+
preamble: preambleNames && preambleNames.size > 0 ? { declaredNames: [...preambleNames] } : undefined
|
|
13531
|
+
});
|
|
13532
|
+
}
|
|
13511
13533
|
function decideWrapFromAstFlags(node) {
|
|
13512
13534
|
if (node.origin && isReactiveOrigin(node.origin)) {
|
|
13513
13535
|
return { wrap: true, reason: "proven-reactive" };
|
|
@@ -13536,12 +13558,12 @@ function decideWrapForChildProp(expandedValue, ctx, prop) {
|
|
|
13536
13558
|
}
|
|
13537
13559
|
function needsEffectWrapper(expr, ctx, freeIdentifiers2) {
|
|
13538
13560
|
for (const signal of ctx.signals) {
|
|
13539
|
-
if (
|
|
13561
|
+
if (identifierCallPattern(signal.getter).test(expr)) {
|
|
13540
13562
|
return true;
|
|
13541
13563
|
}
|
|
13542
13564
|
}
|
|
13543
13565
|
for (const memo of ctx.memos) {
|
|
13544
|
-
if (
|
|
13566
|
+
if (identifierCallPattern(memo.name).test(expr)) {
|
|
13545
13567
|
return true;
|
|
13546
13568
|
}
|
|
13547
13569
|
}
|
|
@@ -13731,8 +13753,9 @@ function traverseForComponents(node, components, skipConditionals = false) {
|
|
|
13731
13753
|
}
|
|
13732
13754
|
});
|
|
13733
13755
|
}
|
|
13734
|
-
function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false) {
|
|
13756
|
+
function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
|
|
13735
13757
|
const texts = [];
|
|
13758
|
+
const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
|
|
13736
13759
|
walkIR(node, false, {
|
|
13737
13760
|
...stopAt("loop", "async", "ifStatement"),
|
|
13738
13761
|
expression: ({ node: n, scope: insideConditional }) => {
|
|
@@ -13741,7 +13764,7 @@ function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings,
|
|
|
13741
13764
|
if (n.preambleRegion)
|
|
13742
13765
|
return;
|
|
13743
13766
|
const originFreeIds = freeIdsFromRefs(n.origin?.freeRefs);
|
|
13744
|
-
const expanded = expandConstantForReactivity(n.expr, ctx, originFreeIds);
|
|
13767
|
+
const expanded = expandConstantForReactivity(n.expr, ctx, originFreeIds, scope);
|
|
13745
13768
|
const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || decideWrapFromAstFlags(n).wrap;
|
|
13746
13769
|
if (!reactive)
|
|
13747
13770
|
return;
|
|
@@ -13765,8 +13788,9 @@ function anyNameIn(names, set) {
|
|
|
13765
13788
|
return true;
|
|
13766
13789
|
return false;
|
|
13767
13790
|
}
|
|
13768
|
-
function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames) {
|
|
13791
|
+
function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames, loopIndex) {
|
|
13769
13792
|
const attrs = [];
|
|
13793
|
+
const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
|
|
13770
13794
|
traverseElements(node, (el) => {
|
|
13771
13795
|
if (el.slotId) {
|
|
13772
13796
|
for (const attr of el.attrs) {
|
|
@@ -13779,7 +13803,7 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings,
|
|
|
13779
13803
|
const valueStr = attrValueToString(attr.value);
|
|
13780
13804
|
if (!valueStr)
|
|
13781
13805
|
continue;
|
|
13782
|
-
const expanded = expandConstantForReactivity(valueStr, ctx, attr.freeIdentifiers);
|
|
13806
|
+
const expanded = expandConstantForReactivity(valueStr, ctx, attr.freeIdentifiers, scope);
|
|
13783
13807
|
const readsPreamble = preambleNames !== undefined && preambleNames.size > 0 && anyNameIn(expanded.freeIds ?? extractFreeIdentifiersFromText(expanded.expr), preambleNames);
|
|
13784
13808
|
const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || readsPreamble || attr.callsReactiveGetters || attr.hasFunctionCalls;
|
|
13785
13809
|
if (!attr.clientOnly && !reactive)
|
|
@@ -14084,13 +14108,13 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
14084
14108
|
const emitDepth = fixedDepth ?? scope.depth + 1;
|
|
14085
14109
|
const loopParamsForTemplate = outerLoopParam ? [outerLoopParam, { param: n.param, bindings: n.paramBindings }] : undefined;
|
|
14086
14110
|
const template = n.children.map((c) => irToPlaceholderTemplate(c, undefined, emitDepth, loopParamsForTemplate)).join("");
|
|
14087
|
-
const refsOuter = outerLoopParam ?
|
|
14111
|
+
const refsOuter = outerLoopParam ? identifierPattern(outerLoopParam).test(n.array) : false;
|
|
14088
14112
|
const bindings = emptyLoopChildBindings();
|
|
14089
14113
|
const innerPreambleNames = preambleNamesOf(n);
|
|
14090
14114
|
if (ctx) {
|
|
14091
14115
|
for (const child of n.children) {
|
|
14092
|
-
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings));
|
|
14093
|
-
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, false, innerPreambleNames));
|
|
14116
|
+
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings, false, innerPreambleNames, n.index));
|
|
14117
|
+
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, false, innerPreambleNames, n.index));
|
|
14094
14118
|
bindings.refs.push(...collectLoopChildRefs(child));
|
|
14095
14119
|
}
|
|
14096
14120
|
}
|
|
@@ -14117,7 +14141,7 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
14117
14141
|
bindings.events.push(...collectLoopChildEventsWithNesting(child));
|
|
14118
14142
|
}
|
|
14119
14143
|
if (ctx) {
|
|
14120
|
-
bindings.conditionals.push(...collectLoopChildConditionals({ type: "fragment", children: n.children, loc: n.loc }, ctx, siblingOffsets, n.param, n.paramBindings));
|
|
14144
|
+
bindings.conditionals.push(...collectLoopChildConditionals({ type: "fragment", children: n.children, loc: n.loc }, ctx, siblingOffsets, n.param, n.paramBindings, innerPreambleNames, n.index));
|
|
14121
14145
|
}
|
|
14122
14146
|
}
|
|
14123
14147
|
result.push({
|
|
@@ -14313,7 +14337,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
14313
14337
|
return;
|
|
14314
14338
|
const projectionInner = l.method === "flatMap" && l.children.length === 1 && l.children[0].type === "loop" ? l.children[0] : undefined;
|
|
14315
14339
|
const childHandlers = [];
|
|
14316
|
-
const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l));
|
|
14340
|
+
const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l), l.index);
|
|
14317
14341
|
if (!projectionInner) {
|
|
14318
14342
|
for (const child of l.children) {
|
|
14319
14343
|
childHandlers.push(...collectEventHandlersFromIR(child));
|
|
@@ -14568,7 +14592,7 @@ function collectBranchLoops(node, ctx, siblingOffsets) {
|
|
|
14568
14592
|
} else {
|
|
14569
14593
|
childTemplate = n.children.map((c) => irToHtmlTemplate(c, undefined, 0, branchLoopParamSpec)).join("");
|
|
14570
14594
|
}
|
|
14571
|
-
const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n)) : emptyLoopChildBindings();
|
|
14595
|
+
const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n), n.index) : emptyLoopChildBindings();
|
|
14572
14596
|
loops.push({
|
|
14573
14597
|
kind: "branch",
|
|
14574
14598
|
array: n.array,
|
|
@@ -14654,19 +14678,20 @@ function preambleNamesOf(loop) {
|
|
|
14654
14678
|
const declared = loop.preamble?.declaredNames;
|
|
14655
14679
|
return declared && declared.length > 0 ? new Set(declared) : undefined;
|
|
14656
14680
|
}
|
|
14657
|
-
function collectLoopChildBindings(children, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames) {
|
|
14681
|
+
function collectLoopChildBindings(children, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
|
|
14658
14682
|
const bindings = emptyLoopChildBindings();
|
|
14659
14683
|
for (const child of children) {
|
|
14660
14684
|
bindings.events.push(...collectLoopChildEventsWithNesting(child));
|
|
14661
|
-
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true, preambleNames));
|
|
14662
|
-
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, loopParam, loopParamBindings, true));
|
|
14685
|
+
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex));
|
|
14686
|
+
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex));
|
|
14663
14687
|
bindings.refs.push(...collectLoopChildRefs(child));
|
|
14664
|
-
bindings.conditionals.push(...collectLoopChildConditionals(child, ctx, siblingOffsets, loopParam, loopParamBindings));
|
|
14688
|
+
bindings.conditionals.push(...collectLoopChildConditionals(child, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex));
|
|
14665
14689
|
}
|
|
14666
14690
|
return bindings;
|
|
14667
14691
|
}
|
|
14668
|
-
function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings) {
|
|
14692
|
+
function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
|
|
14669
14693
|
const conditionals = [];
|
|
14694
|
+
const scope = buildLoopRowScope(loopParam, loopParamBindings, preambleNames, loopIndex);
|
|
14670
14695
|
const refsAnyBindingViaFreeIds = (freeIds) => {
|
|
14671
14696
|
if (loopParamBindings && loopParamBindings.length > 0) {
|
|
14672
14697
|
for (const b of loopParamBindings) {
|
|
@@ -14686,7 +14711,7 @@ function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loop
|
|
|
14686
14711
|
const refsLoopParamInSource = refsAnyBindingViaFreeIds(sourceFreeIds);
|
|
14687
14712
|
if (!n.reactive && !refsLoopParamInSource)
|
|
14688
14713
|
return;
|
|
14689
|
-
const expanded = expandConstantForReactivity(n.condition, ctx, sourceFreeIds);
|
|
14714
|
+
const expanded = expandConstantForReactivity(n.condition, ctx, sourceFreeIds, scope);
|
|
14690
14715
|
if (classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind === "none")
|
|
14691
14716
|
return;
|
|
14692
14717
|
const loopParamsForCond = loopParam ? [{ param: loopParam, bindings: loopParamBindings }] : undefined;
|
|
@@ -14697,23 +14722,23 @@ function collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loop
|
|
|
14697
14722
|
condition: expanded.expr,
|
|
14698
14723
|
whenTrueHtml,
|
|
14699
14724
|
whenFalseHtml,
|
|
14700
|
-
whenTrue: summarizeLoopChildBranch(n.whenTrue, ctx, siblingOffsets, loopParam, loopParamBindings),
|
|
14701
|
-
whenFalse: summarizeLoopChildBranch(n.whenFalse, ctx, siblingOffsets, loopParam, loopParamBindings),
|
|
14725
|
+
whenTrue: summarizeLoopChildBranch(n.whenTrue, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
|
|
14726
|
+
whenFalse: summarizeLoopChildBranch(n.whenFalse, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
|
|
14702
14727
|
...expanded.freeIds !== undefined && { conditionFreeIdentifiers: expanded.freeIds }
|
|
14703
14728
|
});
|
|
14704
14729
|
}
|
|
14705
14730
|
});
|
|
14706
14731
|
return conditionals;
|
|
14707
14732
|
}
|
|
14708
|
-
function summarizeLoopChildBranch(node, ctx, siblingOffsets, loopParam, loopParamBindings) {
|
|
14733
|
+
function summarizeLoopChildBranch(node, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex) {
|
|
14709
14734
|
const inner = collectInnerLoops([node], siblingOffsets, loopParam, ctx, branchInnerLoopOptions);
|
|
14710
14735
|
return {
|
|
14711
14736
|
childComponents: collectConditionalBranchChildComponents(node),
|
|
14712
14737
|
innerLoops: inner.length > 0 ? inner : undefined,
|
|
14713
|
-
conditionals: collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings),
|
|
14738
|
+
conditionals: collectLoopChildConditionals(node, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames, loopIndex),
|
|
14714
14739
|
events: collectConditionalBranchEvents(node),
|
|
14715
|
-
reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, true),
|
|
14716
|
-
reactiveTexts: node.type === "expression" && node.hasFunctionCalls ? [] : collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, true)
|
|
14740
|
+
reactiveAttrs: collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex),
|
|
14741
|
+
reactiveTexts: node.type === "expression" && node.hasFunctionCalls ? [] : collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings, true, preambleNames, loopIndex)
|
|
14717
14742
|
};
|
|
14718
14743
|
}
|
|
14719
14744
|
|
|
@@ -15285,7 +15310,7 @@ var MODULE_CONSTANTS_PLACEHOLDER = "/* __MODULE_LEVEL_CONSTANTS__ */";
|
|
|
15285
15310
|
function detectUsedImports(code) {
|
|
15286
15311
|
const used = new Set;
|
|
15287
15312
|
for (const name of RUNTIME_IMPORT_CANDIDATES) {
|
|
15288
|
-
if (
|
|
15313
|
+
if (identifierCallPattern(name).test(code)) {
|
|
15289
15314
|
used.add(name);
|
|
15290
15315
|
}
|
|
15291
15316
|
}
|
|
@@ -15686,7 +15711,7 @@ function containsAnyIdentifier(node, names) {
|
|
|
15686
15711
|
function scanRefsByName(text, bindings) {
|
|
15687
15712
|
const result = new Map;
|
|
15688
15713
|
for (const name of bindings.keys()) {
|
|
15689
|
-
const re =
|
|
15714
|
+
const re = identifierPattern(name);
|
|
15690
15715
|
if (re.test(text))
|
|
15691
15716
|
result.set(name, []);
|
|
15692
15717
|
}
|
|
@@ -18354,7 +18379,7 @@ function buildStaticArrayDelegationPlan(elem, profileComponentName) {
|
|
|
18354
18379
|
function buildKeyedOrIndexLookup(args) {
|
|
18355
18380
|
const hasBindings = (args.paramBindings?.length ?? 0) > 0;
|
|
18356
18381
|
if (args.key !== null) {
|
|
18357
|
-
const keyWithItem = hasBindings ? substituteLoopBindings(args.key, args.paramBindings, "item") : args.key.replace(
|
|
18382
|
+
const keyWithItem = hasBindings ? substituteLoopBindings(args.key, args.paramBindings, "item") : args.key.replace(identifierPattern(args.param, "g"), "item");
|
|
18358
18383
|
return {
|
|
18359
18384
|
kind: "keyed",
|
|
18360
18385
|
arrayExpr: args.array,
|
|
@@ -20560,7 +20585,7 @@ function emitKeyedLookup(ls, ev, handlerCall, lookup) {
|
|
|
20560
20585
|
}
|
|
20561
20586
|
for (const nested of ev.nestedLoops) {
|
|
20562
20587
|
const rawKey = nested.key ?? "";
|
|
20563
|
-
const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(
|
|
20588
|
+
const innerKeyExpr = nested.paramBindings && nested.paramBindings.length > 0 ? substituteLoopBindings(rawKey, nested.paramBindings, "item") : rawKey.replace(identifierPattern(nested.param, "g"), "item");
|
|
20564
20589
|
const outerRef = hasBindings ? "__bfLoopItem" : param;
|
|
20565
20590
|
ls.push(` const ${nested.param} = ${outerRef} && ${nested.array}.find(item => String(${innerKeyExpr}) === innerKey${nested.depth})`);
|
|
20566
20591
|
}
|
|
@@ -21254,7 +21279,7 @@ function rewritePropsObjectRef(code, propsObjectName) {
|
|
|
21254
21279
|
const srcPropsName = propsObjectName ?? "props";
|
|
21255
21280
|
if (srcPropsName === PROPS_PARAM)
|
|
21256
21281
|
return code;
|
|
21257
|
-
if (!
|
|
21282
|
+
if (!identifierPattern(srcPropsName).test(code))
|
|
21258
21283
|
return code;
|
|
21259
21284
|
const sourceFile = ts19.createSourceFile("init-body.ts", code, ts19.ScriptTarget.Latest, true, ts19.ScriptKind.TS);
|
|
21260
21285
|
const spans = [];
|
|
@@ -23664,7 +23689,7 @@ class JsxAdapter extends BaseAdapter {
|
|
|
23664
23689
|
lines.push(` const ${signal.getter} = () => ${initialValue}`);
|
|
23665
23690
|
}
|
|
23666
23691
|
if (signal.setter) {
|
|
23667
|
-
const setterUsed =
|
|
23692
|
+
const setterUsed = identifierPattern(signal.setter).test(setterRefText);
|
|
23668
23693
|
if (setterUsed) {
|
|
23669
23694
|
lines.push(` const ${signal.setter} = (..._args: any[]) => {}`);
|
|
23670
23695
|
}
|
|
@@ -23862,6 +23887,7 @@ class JsxAdapter extends BaseAdapter {
|
|
|
23862
23887
|
}
|
|
23863
23888
|
|
|
23864
23889
|
// ../jsx/src/adapters/template-imports.ts
|
|
23890
|
+
import ts25 from "typescript";
|
|
23865
23891
|
var CLIENT_PACKAGE_SOURCES = new Set([
|
|
23866
23892
|
"@barefootjs/client",
|
|
23867
23893
|
"@barefootjs/client/runtime"
|
|
@@ -24251,11 +24277,11 @@ function registerBuiltinLoweringPlugins() {
|
|
|
24251
24277
|
registerLoweringPlugin(plugin);
|
|
24252
24278
|
}
|
|
24253
24279
|
// ../jsx/src/combine-client-js.ts
|
|
24254
|
-
import ts25 from "typescript";
|
|
24255
|
-
// ../jsx/src/debug.ts
|
|
24256
24280
|
import ts26 from "typescript";
|
|
24257
|
-
// ../jsx/src/
|
|
24281
|
+
// ../jsx/src/debug.ts
|
|
24258
24282
|
import ts27 from "typescript";
|
|
24283
|
+
// ../jsx/src/profiler.ts
|
|
24284
|
+
import ts28 from "typescript";
|
|
24259
24285
|
|
|
24260
24286
|
// ../jsx/src/index.ts
|
|
24261
24287
|
registerBuiltinLoweringPlugins();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/vite",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.4",
|
|
4
4
|
"description": "Vite plugin for BarefootJS: Vite/Rollup owns bundling, hashing, chunking, tree-shaking and minification of client assets, BarefootJS keeps only the JSX to (template, client JS) compile",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,17 +38,17 @@
|
|
|
38
38
|
"directory": "packages/vite"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@barefootjs/shared": "0.31.
|
|
41
|
+
"@barefootjs/shared": "0.31.4"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@barefootjs/jsx": ">=0.2.0",
|
|
45
45
|
"vite": "^6.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@barefootjs/client": "0.31.
|
|
49
|
-
"@barefootjs/go-template": "0.31.
|
|
50
|
-
"@barefootjs/hono": "0.31.
|
|
51
|
-
"@barefootjs/jsx": "0.31.
|
|
48
|
+
"@barefootjs/client": "0.31.4",
|
|
49
|
+
"@barefootjs/go-template": "0.31.4",
|
|
50
|
+
"@barefootjs/hono": "0.31.4",
|
|
51
|
+
"@barefootjs/jsx": "0.31.4",
|
|
52
52
|
"typescript": "^5.0.0",
|
|
53
53
|
"vite": "^6.0.0"
|
|
54
54
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression (#2588): a relative specifier inside a DYNAMIC `import()` must
|
|
3
|
+
* be re-anchored to the emitted template's directory, exactly like the
|
|
4
|
+
* static `import` statements `rewriteImportsForTemplate` already handles.
|
|
5
|
+
*
|
|
6
|
+
* Dynamic imports never reach `ir.metadata.templateImports` — they ride
|
|
7
|
+
* along inside declaration source text that the adapter re-emits verbatim
|
|
8
|
+
* (`generateModuleScopeDeclarations`' consts/functions, and a component
|
|
9
|
+
* body's local handlers). Before the fix they were emitted untouched, so a
|
|
10
|
+
* specifier written relative to `components/` still said `../lib/heavy`
|
|
11
|
+
* once the template landed in `app/dist/components/` — a path that does
|
|
12
|
+
* not exist. The backend bundler then hard-fails (`Could not resolve
|
|
13
|
+
* "../lib/heavy"`), so this is a build break, not a type-only defect.
|
|
14
|
+
*
|
|
15
|
+
* The fixture mirrors the layout that hits this in the wild (piconic-ai/koma):
|
|
16
|
+
* a `components` dir and a plain `lib` dir side by side, with templates
|
|
17
|
+
* emitted to a DEEPER directory — root-relative and template-relative only
|
|
18
|
+
* diverge when the two depths differ, so a flat layout would not reproduce.
|
|
19
|
+
* Lives under `packages/vite/` (not a system tmpdir) so `@barefootjs/client`
|
|
20
|
+
* resolves through the monorepo's real workspace symlinks — same reason
|
|
21
|
+
* `e2e-fixture`/`e2e-fixture-dev`/`e2e-fixture-relimport` do.
|
|
22
|
+
*/
|
|
23
|
+
import { describe, test, expect, afterAll } from 'bun:test'
|
|
24
|
+
import { build } from 'vite'
|
|
25
|
+
import { mkdtemp, rm, readFile } from 'node:fs/promises'
|
|
26
|
+
import { tmpdir } from 'node:os'
|
|
27
|
+
import { join, resolve } from 'node:path'
|
|
28
|
+
import { HonoAdapter } from '@barefootjs/hono/adapter'
|
|
29
|
+
import { barefoot } from '../plugin.ts'
|
|
30
|
+
|
|
31
|
+
const FIXTURE_ROOT = resolve(import.meta.dirname, '../../e2e-fixture-dynimport')
|
|
32
|
+
const APP_ROOT = join(FIXTURE_ROOT, 'app')
|
|
33
|
+
const COMPONENTS_DIR = join(FIXTURE_ROOT, 'components')
|
|
34
|
+
|
|
35
|
+
// `app/dist/components/Lazy.tsx` → up three → the fixture root, where `lib/`
|
|
36
|
+
// sits. The source says `../lib/heavy` from `components/`; the emitted
|
|
37
|
+
// template has to say this instead.
|
|
38
|
+
const REANCHORED = '../../../lib/heavy'
|
|
39
|
+
|
|
40
|
+
describe('dynamic import() re-anchoring in emitted templates', () => {
|
|
41
|
+
let outDir: string
|
|
42
|
+
let templatesDir: string
|
|
43
|
+
|
|
44
|
+
afterAll(async () => {
|
|
45
|
+
await rm(outDir, { recursive: true, force: true })
|
|
46
|
+
await rm(join(APP_ROOT, 'dist'), { recursive: true, force: true })
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('re-anchors dynamic imports at module scope, in type position, and inside a component body', async () => {
|
|
50
|
+
outDir = await mkdtemp(join(tmpdir(), 'barefoot-vite-dynimport-dist-'))
|
|
51
|
+
templatesDir = join(APP_ROOT, 'dist/components')
|
|
52
|
+
|
|
53
|
+
await build({
|
|
54
|
+
configFile: false,
|
|
55
|
+
root: APP_ROOT,
|
|
56
|
+
base: '/static/',
|
|
57
|
+
logLevel: 'warn',
|
|
58
|
+
build: { outDir, emptyOutDir: true },
|
|
59
|
+
plugins: [
|
|
60
|
+
barefoot({
|
|
61
|
+
adapter: new HonoAdapter(),
|
|
62
|
+
components: [COMPONENTS_DIR],
|
|
63
|
+
templates: templatesDir,
|
|
64
|
+
}),
|
|
65
|
+
],
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const template = await readFile(join(templatesDir, 'Lazy.tsx'), 'utf8')
|
|
69
|
+
|
|
70
|
+
// Nothing anywhere may still carry the source-relative form. Asserted
|
|
71
|
+
// first and globally: a per-site check would pass while some fourth
|
|
72
|
+
// emission path silently leaked the old specifier.
|
|
73
|
+
expect(template).not.toContain("'../lib/heavy'")
|
|
74
|
+
|
|
75
|
+
// Module scope, TYPE position — `typeof import('…')` is an
|
|
76
|
+
// ImportTypeNode, a different AST node from the call expression below,
|
|
77
|
+
// and was missed independently.
|
|
78
|
+
expect(template).toContain(`typeof import('${REANCHORED}')`)
|
|
79
|
+
|
|
80
|
+
// Module scope, VALUE position — inside a re-emitted const's body.
|
|
81
|
+
expect(template).toContain(`modPromise = import('${REANCHORED}')`)
|
|
82
|
+
|
|
83
|
+
// Component scope — inside a local handler in the component body,
|
|
84
|
+
// which is emitted by a different code path than module declarations.
|
|
85
|
+
expect(template).toContain(`await import('${REANCHORED}')`)
|
|
86
|
+
|
|
87
|
+
// The re-anchored path must actually resolve on disk from the emitted
|
|
88
|
+
// template's own directory — the assertions above only pin the string.
|
|
89
|
+
const target = resolve(templatesDir, REANCHORED + '.ts')
|
|
90
|
+
expect(await readFile(target, 'utf8')).toContain('export function heavy')
|
|
91
|
+
}, 60_000)
|
|
92
|
+
})
|