{"id":13725605,"url":"https://github.com/arialpew/reason-loadable","last_synced_at":"2025-05-07T20:33:01.879Z","repository":{"id":27854196,"uuid":"115370984","full_name":"arialpew/reason-loadable","owner":"arialpew","description":"🔥 Suspense/Lazy for ReasonReact.","archived":true,"fork":false,"pushed_at":"2022-02-27T13:12:53.000Z","size":1717,"stargazers_count":90,"open_issues_count":0,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-05-23T07:05:03.919Z","etag":null,"topics":["bucklescript","code-splitting","component","dynamic","hook-component","import","lazy","reasonml","reasonreact","suspense"],"latest_commit_sha":null,"homepage":"https://npmjs.com/reason-loadable","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arialpew.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-26T00:36:51.000Z","updated_at":"2023-09-07T01:31:42.000Z","dependencies_parsed_at":"2022-08-07T13:01:16.618Z","dependency_job_id":null,"html_url":"https://github.com/arialpew/reason-loadable","commit_stats":null,"previous_names":["kmeillet/reason-loadable"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arialpew%2Freason-loadable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arialpew%2Freason-loadable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arialpew%2Freason-loadable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arialpew%2Freason-loadable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arialpew","download_url":"https://codeload.github.com/arialpew/reason-loadable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224645438,"owners_count":17346158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bucklescript","code-splitting","component","dynamic","hook-component","import","lazy","reasonml","reasonreact","suspense"],"created_at":"2024-08-03T01:02:28.757Z","updated_at":"2024-11-14T15:31:35.408Z","avatar_url":"https://github.com/arialpew.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Summary\r\n\r\n[![Build Status](https://travis-ci.org/kMeillet/reason-loadable.svg?branch=master)](https://travis-ci.org/kMeillet/reason-loadable)\r\n![NPM license](https://img.shields.io/npm/l/reason-loadable.svg?style=flat)\r\n\r\n🔥 [Suspense/Lazy](https://reactjs.org/docs/code-splitting.html) for [ReasonReact](https://github.com/reasonml/reason-react).\r\n\r\n* [Installation](#installation)\r\n* [Support](#support)\r\n* [Example](#example)\r\n* [Non-ReasonReact component](#non-reasonreact-component)\r\n* [Experimental SuspenseList](#experimental-suspenselist)\r\n* [API](#api)\r\n* [Special thanks to](#special-thanks-to)\r\n\r\n# Installation\r\n\r\n```sh\r\nnpm install reason-loadable --save\r\n```\r\n\r\nThen add \"reason-loadable\" in \"bsconfig.json\" :\r\n\r\n```sh\r\n\"bs-dependencies\": [\r\n \"reason-loadable\"\r\n]\r\n```\r\n\r\nYou can now use **\"ReLoadable\"** module.\r\n\r\n**Note :** **\"ReLoadable\"** contain type definition, it doesn't add any single bit into your project.\r\n\r\n# Support\r\n\r\n* **[ReasonReact](https://github.com/reasonml/reason-react) component (JSX v3)**. ✔️\r\n* **Non-ReasonReact component (third-party React component or your own plain JavaScript React component)**. ✔️\r\n\r\n[ReasonReact](https://github.com/reasonml/reason-react) JSX v2 isn't supported : Please consider migrating to JSX v3 (new [ReasonReact](https://github.com/reasonml/reason-react) hook components).\r\n\r\n# Example\r\n\r\n1) Create a [ReasonReact](https://github.com/reasonml/reason-react) hook component (JSX v3).\r\n\r\n```reason\r\n/* HelloWorld.re */\r\n[@react.component]\r\nlet make = (~name) =\u003e \u003ch1\u003e (React.string(\"Hello world \" ++ name)) \u003c/h1\u003e;\r\n\r\n/* Export default is necessary because React lazy function always resolve the default export. */\r\nlet default = make;\r\n```\r\n\r\n2) Create type-safe lazy component with **\"ReLoadable.lazy_\"** and **\"ReLoadable.import\"**.\r\n\r\n```reason\r\n/* LazyHelloWorld.re */\r\nmodule type T = (module type of WithPure);\r\n\r\n/*\r\n  Needed for BuckleScript to not import the original component :\r\n  See https://github.com/BuckleScript/bucklescript/issues/3543\r\n*/\r\nlet unsafePlaceholder: module T = [%raw {|{}|}];\r\n\r\nmodule UnsafePlaceholder = (val unsafePlaceholder);\r\n\r\nlet makeProps = UnsafePlaceholder.makeProps;\r\n\r\nlet make =\r\n  ReLoadable.lazy_(() =\u003e ReLoadable.import(UnsafePlaceholder.make, \"./HelloWord.bs.js\"));\r\n```\r\n\r\n3) Render lazy component anywhere in your [ReasonReact](https://github.com/reasonml/reason-react) app with **\"React.Suspense\"**.\r\n\r\n```reason\r\n/* App.re */\r\n[@react.component]\r\nlet make = () =\u003e {\r\n  \u003cReact.Suspense fallback={\u003cdiv\u003e (React.string(\"Loading ...\")) \u003c/div\u003e}\u003e\r\n    \u003cLazyHelloWorld name=\"Zeus\" /\u003e\r\n  \u003c/React.Suspense\u003e;\r\n};\r\n```\r\n\r\n[More example are available in repository.](https://github.com/kMeillet/reason-loadable/tree/master/examples)\r\n\r\n# Non-ReasonReact component\r\n\r\n1) Create type-safe lazy component with **\"ReLoadable.lazy_\"** and **\"ReLoadable.import\"**.\r\n\r\n```reason\r\n/* LazyButton.re */\r\n/* You have to type non-ReasonReact component props explicitly. */\r\nmodule type T = {\r\n  [@react.component]\r\n  let make: (~text: string) =\u003e React.element;\r\n};\r\n\r\n/*\r\n  Needed for BuckleScript to not import the original component :\r\n  See https://github.com/BuckleScript/bucklescript/issues/3543\r\n*/\r\nlet unsafePlaceholder: module T = [%raw {|{}|}];\r\n\r\nmodule UnsafePlaceholder = (val unsafePlaceholder);\r\n\r\nlet makeProps = UnsafePlaceholder.makeProps;\r\n\r\n/* \"@my-component-lib/button\" should have a default export. */\r\nlet make =\r\n  ReLoadable.lazy_(() =\u003e ReLoadable.import(UnsafePlaceholder.make, \"@my-component-lib/button\"));\r\n```\r\n\r\n2) Render lazy component anywhere in your [ReasonReact](https://github.com/reasonml/reason-react) app with **\"React.Suspense\"**.\r\n\r\n```reason\r\n/* App.re */\r\n[@react.component]\r\nlet make = () =\u003e {\r\n  \u003cReact.Suspense fallback={\u003cdiv\u003e (React.string(\"Loading ...\")) \u003c/div\u003e}\u003e\r\n    \u003cLazyButton text=\"Click !\" /\u003e\r\n  \u003c/React.Suspense\u003e;\r\n};\r\n```\r\n\r\n# Experimental SuspenseList\r\n\r\n[Concurrent mode](https://reactjs.org/docs/concurrent-mode-intro.html) is only available in the experimental builds of React. To install them, run :\r\n\r\n```sh\r\nnpm install react@experimental react-dom@experimental\r\n```\r\n\r\nThere are no semantic versioning guarantees for the experimental builds. APIs may be added, changed, or removed with any @experimental release.\r\n\r\n[Experimental releases will have frequent breaking changes](https://reactjs.org/docs/concurrent-mode-adoption.html).\r\n\r\nYou can try these builds on personal projects or in a branch, but we don’t recommend running them in production.\r\n\r\nSometime, there's breaking change in experimental builds. For example, \"createRoot\" function has been changed to \"unstable_createRoot\" recently. \r\n\r\nBe prepared to do some research into ReasonReact and React source code if something goes wrong, especially when binding between ReasonReact and React doesn't match due to breaking changes.\r\n\r\n**Experimental ReasonReact API is available under the \"Experimental\" module :** https://github.com/reasonml/reason-react/blob/master/src/ReactDOMRe.re#L40\r\n\r\nSome React experimental builds can break the SuspenseList API.\r\n\r\nHere is one experimental build that seem to work well with SuspenseList API : **0.0.0-experimental-aae83a4b9**.\r\n\r\n```sh\r\nnpm install react@0.0.0-experimental-aae83a4b9 react-dom@0.0.0-experimental-aae83a4b9\r\n```\r\n\r\n```reason\r\n/* App.re */\r\n/* LazyButton and LazyHelloWorld are lazy components (see previous examples). */\r\n[@react.component]\r\nlet make = () =\u003e {\r\n  \u003cReact.SuspenseList\u003e\r\n    \u003cReact.Suspense fallback={\u003cdiv\u003e (React.string(\"Loading ...\")) \u003c/div\u003e}\u003e\r\n      \u003cLazyButton text=\"Click !\" /\u003e\r\n    \u003c/React.Suspense\u003e\r\n    \u003cReact.Suspense fallback={\u003cdiv\u003e (React.string(\"Loading ...\")) \u003c/div\u003e}\u003e\r\n      \u003cLazyHelloWorld name=\"Zeus\" /\u003e\r\n    \u003c/React.Suspense\u003e\r\n  \u003c/React.SuspenseList\u003e;\r\n};\r\n```\r\n\r\n```reason\r\n/* index.re */\r\n/* You have to use the experimental createRoot API explicitly. */\r\nlet _ =\r\n  switch (ReactDOMRe.Experimental.createRootWithId(\"root\")) {\r\n  | Ok(root) =\u003e ReactDOMRe.Experimental.render(root, \u003cApp /\u003e)\r\n  | Error(err) =\u003e Js.log(err)\r\n  };\r\n```\r\n\r\n# API\r\n\r\n#### `ReLoadable.import: (Js.t('a) =\u003e React.element), string) =\u003e Js.Promise.t(Js.t('a) =\u003e React.element)`\r\n\r\nDynamic import React component.\r\n\r\n#### `ReLoadable.lazy_: (unit =\u003e Js.Promise.t('a)) =\u003e 'a`\r\n\r\n[React.lazy](https://reactjs.org/docs/code-splitting.html) binding.\r\n\r\n# Special thanks to\r\n\r\n- @rickyvetter\r\n\r\n- @bloodyowl\r\n\r\n- @cristianoc\r\n\r\n- @thangngoc89\r\n\r\n- @jchavarri (https://github.com/jchavarri/reason-react-lazy-loading)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farialpew%2Freason-loadable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farialpew%2Freason-loadable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farialpew%2Freason-loadable/lists"}