-
Notifications
You must be signed in to change notification settings - Fork 349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PPX proposal: React.lazy #498
Comments
I haven't had the chance to use React.lazy or React.Suspense yet, and haven't tested the following code, but I gave it a shot at approximating your example transformation with reason-macros: // MyComponent.re
[@react.component]
let make = (~title=?, ~children) => <div ?title> children </div>; // MyComponentLazy.re
%react.lazy
(MyComponent, "./MyComponent.bs.js"); // Shared.macros.re
[@macro.name "react.lazy"]
let%macro.toplevel _ =
(moduleName: capIdent, modulePath: string) => [%str
include (
{
[@bs.val]
external import:
([@bs.as "$eval{modulePath}"] _, unit) => Js.Promise.t('a) =
"import";
[@bs.module "react"]
external lazy_: (unit => Js.Promise.t('a)) => 'a = "lazy";
let makeProps = Eval__moduleName.makeProps;
let make =
lazy_(() =>
import()
|> Js.Promise.then_(x =>
Js.Promise.resolve({"default": x##make}) |> Obj.magic
)
);
}:
(module type of {
let makeProps = Eval__moduleName.makeProps;
let make = Eval__moduleName.make;
})
)
]; // Generated MyComponentLazy module type
{
let makeProps:
(~title: 'a=?, ~children: 'b, ~key: string=?, unit) =>
{. "children": 'b, "title": option('a)};
let make:
{. "children": React.element, "title": option(string)} => React.element;
} // Generated MyComponentLazy.bs.js
// Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
import * as React from "react";
import * as Caml_option from "../node_modules/bs-platform/lib/es6/caml_option.js";
function makeProps(prim, prim$1, prim$2, prim$3) {
var tmp = {
children: prim$1
};
if (prim !== undefined) {
tmp.title = Caml_option.valFromOption(prim);
}
if (prim$2 !== undefined) {
tmp.key = Caml_option.valFromOption(prim$2);
}
return tmp;
}
var make = React.lazy((function (param) {
return import("./MyComponent.bs.js").then((function (x) {
return Promise.resolve({
default: x.make
});
}));
}));
export {
makeProps ,
make ,
}
/* make Not a pure module */ Would've been easier to do (and also allow us to keep |
I like this concept but we can't implement it until we get a reliable and typesafe way to define |
@bobzhang would that be hard to implement in BuckleScript? |
BTW done a bit more work to research this and I want to document the three things I believe we need from BuckleScript:
Two might seem odd given the way dynamic imports in JS work today, but I think it's actually an improvement as a module author you have more control over how this module is used. This might be able to be done without the annotation, but I think it would be much harder and I am not sure the tradeoffs are worth it. |
@rickyvetter thanks for sharing your research, this is really exciting! |
it's currently pretty hard to get a type-safe dynamic import using BuckleScript. it's even harder to use
React.lazy
.how would you feel about having a PPX:
The text was updated successfully, but these errors were encountered: