Skip to content

Commit 6b0b6be

Browse files
committed
fix(loadable-components): honor final ssr override order (#592)
1 parent 646da79 commit 6b0b6be

3 files changed

Lines changed: 82 additions & 16 deletions

File tree

  • packages/loadable-components

packages/loadable-components/src/lib.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -138,24 +138,40 @@ where
138138
_ => return false,
139139
};
140140

141-
obj.props.iter().any(|prop| match prop {
142-
PropOrSpread::Prop(prop) => match prop.as_ref() {
143-
Prop::KeyValue(kv) => {
144-
let is_ssr_key = match &kv.key {
145-
PropName::Ident(i) => &*i.sym == "ssr",
146-
PropName::Str(s) => s.value == "ssr",
147-
_ => false,
148-
};
149-
is_ssr_key
150-
&& matches!(
141+
// Object literals are order-sensitive. Walk from right to left to find
142+
// the last effective `ssr` assignment. We can only skip when it is
143+
// definitely `false`.
144+
for prop in obj.props.iter().rev() {
145+
match prop {
146+
PropOrSpread::Prop(prop) => match prop.as_ref() {
147+
Prop::KeyValue(kv) => {
148+
let is_ssr_key = match &kv.key {
149+
PropName::Ident(i) => &*i.sym == "ssr",
150+
PropName::Str(s) => s.value == "ssr",
151+
_ => false,
152+
};
153+
154+
if !is_ssr_key {
155+
continue;
156+
}
157+
158+
return matches!(
151159
kv.value.as_ref(),
152160
Expr::Lit(Lit::Bool(Bool { value: false, .. }))
153-
)
154-
}
155-
_ => false,
156-
},
157-
_ => false,
158-
})
161+
);
162+
}
163+
Prop::Shorthand(ident) if &*ident.sym == "ssr" => {
164+
// Dynamic shorthand value: cannot guarantee false.
165+
return false;
166+
}
167+
_ => {}
168+
},
169+
// A spread may provide/override `ssr` dynamically.
170+
PropOrSpread::Spread(_) => return false,
171+
}
172+
}
173+
174+
false
159175
}
160176

161177
fn transform_import_expr(&mut self, call: &mut CallExpr) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import loadable from "@loadable/component";
2+
3+
const opts = { ssr: true };
4+
5+
loadable(() => import("./OtherComponent"), { ssr: false, ...opts });
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import loadable from "@loadable/component";
2+
const opts = {
3+
ssr: true
4+
};
5+
loadable({
6+
resolved: {},
7+
chunkName () {
8+
return "OtherComponent";
9+
},
10+
isReady (props) {
11+
const key = this.resolve(props);
12+
if (this.resolved[key] !== true) {
13+
return false;
14+
}
15+
if (typeof __webpack_modules__ !== 'undefined') {
16+
return !!__webpack_modules__[key];
17+
}
18+
return false;
19+
},
20+
importAsync: ()=>import(/*webpackChunkName: "OtherComponent"*/ "./OtherComponent"),
21+
requireAsync (props) {
22+
const key = this.resolve(props);
23+
this.resolved[key] = false;
24+
return this.importAsync(props).then((resolved)=>{
25+
this.resolved[key] = true;
26+
return resolved;
27+
});
28+
},
29+
requireSync (props) {
30+
const id = this.resolve(props);
31+
if (typeof __webpack_require__ !== 'undefined') {
32+
return __webpack_require__(id);
33+
}
34+
return eval('module.require')(id);
35+
},
36+
resolve () {
37+
if (require.resolveWeak) {
38+
return require.resolveWeak("./OtherComponent");
39+
}
40+
return eval('require.resolve')("./OtherComponent");
41+
}
42+
}, {
43+
ssr: false,
44+
...opts
45+
});

0 commit comments

Comments
 (0)