Code Splitting
The import()
ECMAScript proposal by Domenic Denicola allows dynamically loading modules. It is currently in stage 3 of the TC39 process.
Warning
Support for dynamic imports in Packem using the
dev-plugin
is early. Refer to the issues section of thepackem-plugins
repo.
Example
Just use import()
directly in your code. For example, if you have two modules, A.js and B.js, to dynamically import the latter into the former and log the output, this is how one could accomplish it:
// B.js
export default {
isAvailable: true
};
// A.js
// Using ES6's Promise API:
import("./B").then(console.log);
// Using `async/await` syntax
const exportsOfB = await import("./B");
console.log(exportsOfB);
Under the Hood
In Packem, a dynamically imported module retains its own sub-graph in the module graph. Hypothetically, a simple interface to represent a chain of dynamic imports would look something like this:
export default [
// In essence, Packem fails without the `input` field being defined
// in the configuration file.
{
id: "root",
// Root never exhibits a parent because logically, the main bundle
// cannot be a dynamic module since that would necessate loading into
// some script. This is not a bug, but rather intended.
bundle_id: "",
dependencies: [
// Module `sKAY2qXG` (mangled) is bundled with the root.
"sKAY2qXG"
],
...
},
{
id: "sKAY2qXG",
// If `bundle_parent` corresponds to `root` then it's a regular
// module.
bundle_parent: "root",
dependencies: [
"yFj2CkjK", "vhjv3jjP", "zYqARjUK",
"LPrhSMJz", "b34kURy3", "XnOhbVJ7"
],
...
},
{
id: "yFj2CkjK",
// This is a dynamically imported module that belongs to module
// `b34kURy3`.
bundle_parent: "b34kURy3",
dependencies: [
// Module `sKAY2qXG` (mangled) is bundled with the root.
"sKAY2qXG"
],
...
},
...
] as ModuleGraph;
Before Babel does any transformations, all import()
statements are replaced with the mangled id. The serializer handles fetching of modules which is where the code splitting issue in dev-plugin
originates from.