FormidableLabs/trace-deps

Test Scenario: New Node.js ESM packages.

Closed this issue · 0 comments

Node.js 12+ with ESM support means that based on the upstream import, different files can be imported at runtime. We should have a good test / set of tests around this scenario. Offhand, maybe:

Code

  • Extensions: Make sure the core library handles .cjs and .mjs extensions for importing and filtering.
  • Mode Choices: There are really 3 options -- old CJS (that doesn't consider exports), new CJS (that does consider exports), and new ESM. Possible tokens: NODE_CJS_OLD, NODE_CJS_NEW, NODE_ESM ( This looks tough... )
  • Bundle all export conditions: ( Current approach ) Find all reasonable Node.js conditions (import, require, node, development, production) and package them all. Trade off size for correctness.

Research

Tests

  • Test scenario with a library containing the following and using one, then the other.
    • ESM files
    • CJS files
  • Test scenario with just ESM Node files
  • Figure out how to invoke this in Node 12 (forget if we need a flag)

See https://nodejs.org/api/packages.html#packages_determining_module_system for more details.

Scenario es-get-iterator

From https://unpkg.com/browse/es-get-iterator@1.1.2/ this is the behavior:

  1. Old Node (CJS) uses ./index.js off package.json:main.
  2. New Node + CJS uses exports field with . entry resolving to ./node.js
  3. New Node + ESM uses exports field with . entry resolving to ./node.mjs

Notes

Conditions

From https://nodejs.org/api/packages.html#packages_conditional_exports

  • "import" - matches when the package is loaded via import or import(), or via any top-level import or resolve operation by the ECMAScript module loader. Applies regardless of the module format of the target file. Always mutually exclusive with "require".
  • "require" - matches when the package is loaded via require(). The referenced file should be loadable with require() although the condition matches regardless of the module format of the target file. Expected formats include CommonJS, JSON, and native addons but not ES modules as require() doesn't support them. Always mutually exclusive with "import".
  • "node" - matches for any Node.js environment. Can be a CommonJS or ES module file. This condition should always come after "import" or "require".
  • "default" - the generic fallback that always matches. Can be a CommonJS or ES module file. This condition should always come last.