Skip to content

Instantly share code, notes, and snippets.

@bmeck
Last active January 11, 2017 20:05
Show Gist options
  • Save bmeck/e11d5618ccfa5c7b57f3cae066c54c2e to your computer and use it in GitHub Desktop.
Save bmeck/e11d5618ccfa5c7b57f3cae066c54c2e to your computer and use it in GitHub Desktop.

Named Imports from CJS via Property Delegation

import {readFile} from "fs";
  • Not in the cards
    • Codegen order of operations issue
    • Deopts ala with for all imports even ESM<->ESM
    • Causes Temporal Dead Zone (TDZ) for any non-default CJS import

Async Loader

  • Web-like
    • Browsers preserve order of evaluation but do not guarantee sync SourceTextModuleRecord ModuleEvaluation
    • Browsers fetch/parse async prior to starting any ESM graph loading
  • Allows for gaps in evaluation phase / top level await
    • Would be a standard synchronization system for Web and Node both
  • Works on existing spec w/o changes
  • Avoids a TDZ in circular deps
a (CJS) -> b 
b (ESM) -> a

If b is async (wrapped in a Promise) a cannot access the shape of b including any dynamic shaping of a. This is important if a loader wants to be able to have CJS able create it's shape at runtime (a route for limited named imports from CJS).

If this was sync CJS would have to always unconditionally have an exact shape of {default} to avoid TDZ issues. No solution exists for a loader to mutate the shape afterwards.

If async, a loader could produce a MITM ESM in theory that has the ability to have named imports w/o a TDZ. Such a MITM ESM would require usage of setter functions to update the live bindings and would not be for the faint of heart unfortunately, but possible even w/o Proxies.

Sync Loader

  • CJS-like
    • Node has always sync loading mandate for CJS
  • Babel-like*
    • require("esm") only has minor changes from Babel@6.
    • does not have same mutation qualities of Babel Modules (BM)
    • variables are always live unlike BM
  • Needs https://github.com/caridy/proposal-dynamic-modules to introduce lazy/late linking
    • Introduces a linking TDZ in loader
      • See example about TDZ in circular deps for some context
      • import {non_existant} from "CJS"; would throw at ModuleEvaluation not ModuleDeclarationInstanciation. Which leads to partial graph eval due to linking error (not possible in current spec).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment