[Call for testing] Dynamic import

Introduce the dynamic import (see forum RFC, GitHub discussion)

In this guide, we’ll explain how to use the dynamic import for module and module value. This new feature allows you to express the dynamic import syntax in Javascript in ReScript without having to be concerned about the actual file names and paths. We’ll go through several examples to help you to understand how to use this feature.

  1. Importing a module value
let forEach = await Js.import(Belt.Array.forEach)
let _ = [1, 2]->forEach(_ => ())

compiled to

var forEach = await import("rescript/lib/es6/belt_Array.js").then(function (m) {
  return m.forEach;
});
Curry._2(forEach, [1, 2], (function (param) { }));
  1. Importing a module
module M = await Belt.Array
let forEach2 = M.forEach
let _ = [1, 2]->forEach2(_ => ())

compiled to

var M = await import("rescript/lib/es6/belt_Array.js");
var forEach2 = M.forEach;
Curry._2(forEach2, [1, 2], (function (param) { }));
  1. Lazy importing a React.component
    In cases where React components need to be lazy-loaded, you can use the following approach:
// LazyComponent.res
@react.component
let make = () => React.string("Lazy")

// App.res
module LazyC = await LazyComponent
let c = <LazyC />

FYI, the syntax surface is still a work in progress, so if you apply formatting, the @res.await used before the module may disappear. To test, simply turn off formatting.

EDIT: The await Module syntax has now been added as following binaries.

You can test using the built binaries available at the following address: Dynamic import · rescript-lang/rescript-compiler@6f0c22a · GitHub

12 Likes

It will be better output using destructured await.

Recent versions of modern bundlers support tree-shaking for it.

See:

1 Like

Dynamic import of module is non-determistic, so you mean the dynamic importing of value right?

// as-is
var forEach = await import("rescript/lib/es6/belt_Array.js").then(function (m) {
  return m.forEach;
});

// to-be
var {forEach} = await import("rescript/lib/es6/belt_Array.js")

Maybe you can’t do that with var, only let?

1 Like

So this Test emitting let instead of var. by cristianoc · Pull Request #6102 · rescript-lang/rescript-compiler · GitHub is maybe coming at the right time.

I’m trying to find the reference for destructuring assignment with var, no gain yet. But it seems working when I tested it in the console in the Chrome browser. :thinking:

The lazy import for a react component is great, does it support import a react component module in a file?

Sure, you can. Can you share any use case of your own?

Actually, i would use dynamic import on very few use cases for using nextjs which can automatically split my code.

Maybe you can use this feature like:

// This is API of next.js
@val external dynamic: (unit => Js.Promise.t<'a>, {..}) => 'a = "dynamic"

module L = {
  let make = dynamic(() => Js.import(LazyComp.make), {"ssr": false})
}

<L x="lazy" />
1 Like