Skip to content

Instantly share code, notes, and snippets.

@rickyvetter
Created June 20, 2019 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rickyvetter/17bdaaf1a35880cf1f00d07328254958 to your computer and use it in GitHub Desktop.
Save rickyvetter/17bdaaf1a35880cf1f00d07328254958 to your computer and use it in GitHub Desktop.
example ppx external issue
(*
module <Foo> = {
let makeProps = <Foo>.makeProps;
let make =
React.createElement(
{
module Comp = (val ReasonResource.readOrThrow([%reasonResource <Foo>]));
Comp.make;
},
_,
);
};
*)
let module_expr =
(fun mapper module_expr -> match module_expr with
| ({
pmod_desc = Pmod_extension ({txt = "lazyLoadComponent"}, PStr [ {pstr_desc = Pstr_eval ( {
pexp_desc = Pexp_construct ({txt}, _)
}, _)} ])
} as pmod) -> begin
{ pmod with pmod_desc = Pmod_structure [
Str.value Nonrecursive [
Vb.mk (Pat.var {loc=(!default_loc); txt = "reasonResource"})
(expr mapper (
Exp.extension (
{loc=(!default_loc); txt = "reasonResource"},
PStr [Str.eval (Exp.construct ({loc=(!default_loc); txt}) None)]
)))
];
Str.value Nonrecursive [
Vb.mk (Pat.var {loc=(!default_loc); txt = "makeProps"})
(Exp.ident {loc=(!default_loc); txt = Ldot (txt, "makeProps")})
];
Str.value Nonrecursive [
Vb.mk (Pat.var {loc=(!default_loc); txt = "make"})
(Exp.fun_ "" None (Pat.var {loc=(!default_loc); txt = "props"}) (Exp.apply
(Exp.ident {loc=(!default_loc); txt = Ldot ((Lident "React"), "createElement")}) [
("", (Exp.letmodule
{loc=(!default_loc); txt = "Comp"}
(Mod.unpack (Exp.apply
(Exp.ident {loc=(!default_loc); txt = Ldot ((Lident "ReasonResource"), "readOrThrow")})
[("", Exp.ident {loc=(!default_loc); txt = Lident "reasonResource"})]
))
(Exp.ident {loc=(!default_loc); txt = Ldot ((Lident "Comp"), "make")})
));
("", Exp.ident {loc=(!default_loc); txt = Lident "props"})
]
))
]
]}
end
| _ -> default_mapper.module_expr mapper module_expr
)
@rickyvetter
Copy link
Author

rickyvetter commented Jun 20, 2019

On line 3 - if Foo.makeProps is a value instead of an external the code size in this file will be larger and the asynchronous code loading will be unsuccessful. We'd like to be able to copy this external over and not allow compilation if it's not an external. We can't copy it over because we don't know the type in the ppx.

We can mitigate this issue by calling ReasonResource.readOrThrow in the top level of this module, but then we could throw in a way that React JS isn't ready to handle (outside of it's control flow) - we would also be loading the code before it's strictly needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment