Skip to content

Import defer support #5932

@guybedford

Description

@guybedford

Feature Use Case

The new import defer syntax is at Stage 3 in the TC39 process and implementations are starting to move forward in browsers and tools.

This enables new optimizations in code splitting builds that avoid unnecessary code execution.

Example:

import defer * as mod from './mod.js';

export function lazyModUser () {
  mod.foo();
}

where mod is a "Deferred Module" flavor of Module Namespace, whose accessors (including eg reading keys) cause evaluation to run.

Feature Proposal

Unlike Webpack, RollupJS doesn't wrap by default so may have a harder time implementing this proposal, but ideally, we might imagine bundling deferred modules that aren't externals using module declarations / expressions and import sync in future (proposals still being discussed, not yet fleshed out, so years off still):

module mod {
  // ... source ...
}

export function lazyModUser () {
  import.sync(mod).foo();
}

The point being that semantically and architecturally, these modules represent a nested execution layer at an ESM semantic level, which in future may be true first-class constructs. In the deferred evaluation spec the namespace access is effectively a new type of top-level evaluator - the edge cases very much fit this nested evaluation model.

Wrapper module conversion then might be seen as a new type of layer in RollupJS, ideally in the spirit of the project as a sort of polyfill for the not-yet-existing ability to create these nested modules and synchronous sub-evaluators.

Contiguous blocks of nested module code can effectively be wrapper-ified as a sort of sub-code-split layer where module wrapper groupings match code splitting groupings on deferred subgraphs behind a namespace proxy with the handler calling the module wrapper on access.

const modWrapper = (function () {
  // ...mod source...
});
let modNs = null;
const mod = new Proxy(..., { ...handler that uses the cached modNs namespace or runs the module wrapper to generate it... });

export function laxyModUser () {
  mod.foo();
}

This work may then also lay groundwork for module declarations / expressions and import.sync if these proposals develop, although we are many years off yet so there is no rush here by any means.

//cc @nicolo-ribaudo for discussion here as well.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions