CodeSampleX

Exemple

@rollup/plugin-commonjs 28.0.7: By default @rollup/plugin-commonjs renders external requires as default imports causing named exports to be inaccessible unless esmExternals is configured

Échantillon vérifié pour npm @rollup/plugin-commonjs 28.0.7: By default @rollup/plugin-commonjs renders external requires as default imports causing named…

sha256:4c5bf847bf0aa98a1bfd3b9919628d6ee74bd297513afb48edef8f7e4b2feb30

Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré. Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes. MIT-0

Preuves d'exécution

L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.

Base de preuve
Contrat signé réussi
Reçus de vérification
1
Clés de signature qui l’ont compilé
1
Environnement déclaré node linux 24 · ubuntu · glibc 2.39 x64 node node npm

Environnements des exécutions de vérification

Environnement Contrat Étapes Exécution
node 22 · linux debian/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22@sha256:8a34c4ab3ea2…
2026-09-03

Cas

HOW
Objectif
By default @rollup/plugin-commonjs renders external requires as default imports causing named exports to be inaccessible unless esmExternals is configured
Paquets
Symboles
  • commonjs
  • esmExternals
Environnement
node
Créé
2026-09-03T09:28:03Z

Contrat

  1. assert @rollup/plugin-commonjs with default esmExternals: false emits default imports for external dependencies, causing named exports to be inaccessible (undefined) when required from CommonJS
  2. assert setting esmExternals: true emits namespace imports for external dependencies, creating an augmented namespace that exposes both named exports and default export
  3. assert esmExternals accepts an array of package IDs to selectively emit namespace imports for specified ESM dependencies while leaving other externals as default imports
  4. assert esmExternals accepts a predicate function to dynamically determine which external dependencies are imported as ES module namespaces

Fichiers

  • NOTES.md
  • PROMPT.md
  • csx.json
  • package-lock.json
  • package.json
  • spec.json
  • test/contract.mjs

Télécharger l’artefact source (tar.gz)

Code source

NOTES.md
# Notes: Rollup CommonJS Plugin External ES Modules and esmExternals

## Search Result
`search_known_solution` returned `NO_SAFE_MATCH` for `@rollup/plugin-commonjs@28.0.7` with symbol `esmExternals`. Existing verified samples for this package covered `strictRequires`, `requireReturnsDefault`, and `transformMixedEsModules`, but none demonstrated how external dependencies are handled when required from CommonJS.

## Naive Model Assumption
A developer or coding model assumes that requiring an external ES module from a CommonJS module bundled with `@rollup/plugin-commonjs` preserves access to all exported symbols, including named exports (such as `const { helper } = require('external-pkg')`).

## Failure Mode
By default (`esmExternals: false`), `@rollup/plugin-commonjs` assumes all external dependencies are CommonJS and generates an unknown require proxy that emits only a default import (`export { default } from 'external-pkg'`). When the external ES module defines named exports, attempting to access them in CommonJS evaluates to `undefined`, causing silent functional failures or runtime `TypeError` when calling functions. Enabling `esmExternals: true` (or passing an array of IDs or a predicate function) switches the proxy to import the ES module namespace and wraps it in an augmented namespace, making both named exports and default exports accessible.
PROMPT.md
Clean-room public code sample — generation instructions

Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.

A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.

Goal: By default @rollup/plugin-commonjs renders external requires as default imports causing named exports to be inaccessible unless esmExternals is configured
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/%40rollup/plugin-commonjs@28.0.7
  - pkg:npm/rollup@4.34.8
Demonstrate these symbols/APIs:
  - commonjs
  - esmExternals

Rules:
  - One focused purpose; the smallest project that proves the goal.
  - Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
  - Pin every dependency with a lockfile so resolution is reproducible.
  - No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
  - No personal names, emails, company names, or project identifiers of any kind.
  - No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
  - Keep it under 200 files and 256KB packed.
csx.json
{"case":{"believed":"By default @rollup/plugin-commonjs allows CommonJS modules requiring external ES modules to access both default and named exports.","caseId":"case:sha256:042d2e62034055b487fd659dbd694e3a334e373ef1364a7caa266f6bcb694717","contract":["assert @rollup/plugin-commonjs with default esmExternals: false emits default imports for external dependencies, causing named exports to be inaccessible (undefined) when required from CommonJS","assert setting esmExternals: true emits namespace imports for external dependencies, creating an augmented namespace that exposes both named exports and default export","assert esmExternals accepts an array of package IDs to selectively emit namespace imports for specified ESM dependencies while leaving other externals as default imports","assert esmExternals accepts a predicate function to dynamically determine which external dependencies are imported as ES module namespaces"],"goal":"By default @rollup/plugin-commonjs renders external requires as default imports causing named exports to be inaccessible unless esmExternals is configured","kind":"HOW","packages":["pkg:npm/%40rollup/plugin-commonjs@28.0.7","pkg:npm/rollup@4.34.8"],"schemaVersion":1,"symbols":["commonjs","esmExternals"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","executionContext":"node","language":"node","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/%40rollup/plugin-commonjs@28.0.7","pkg:npm/rollup@4.34.8"],"schemaVersion":1,"symbols":["commonjs","esmExternals"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "npm-rollup-plugin-commonjs-esm-externals",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "npm-rollup-plugin-commonjs-esm-externals",
      "version": "1.0.0",
      "license": "MIT-0",
      "dependencies": {
        "@rollup/plugin-commonjs": "28.0.7",
        "rollup": "4.34.8"
      }
    },
    "node_modules/@jridgewell/sourcemap-codec": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
      "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
      "license": "MIT"
    },
    "node_modules/@rollup/plugin-commonjs": {
      "version": "28.0.7",
      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.7.tgz",
      "integrity": "sha512-6cE2Wr/MkpdtTS8gXlCn9Zdmf7e9Xm96yFqOwFEXuvYLAHtjRf57/n6GEVF4K8NSesT1eKdBtcDA/SQdpW/8nA==",
      "license": "MIT",
      "dependencies": {
        "@rollup/pluginutils": "^5.0.1",
        "commondir": "^1.0.1",
        "estree-walker": "^2.0.2",
        "fdir": "^6.2.0",
        "is-reference": "1.2.1",
        "magic-string": "^0.30.3",
        "picomatch": "^4.0.2"
      },
      "engines": {
        "node": ">=16.0.0 || 14 >= 14.17"
      },
      "peerDependencies": {
        "rollup": "^2.68.0||^3.0.0||^4.0.0"
      },
      "peerDependenciesMeta": {
        "rollup": {
          "optional": true
        }
      }
    },
    "node_modules/@rollup/pluginutils": {
      "version": "5.4.0",
      "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz",
      "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==",
      "license": "MIT",
      "dependencies": {
        "@types/estree": "^1.0.0",
        "estree-walker": "^2.0.2",
        "picomatch": "^4.0.2"
      },
      "engines": {
        "node": ">=14.0.0"
      },
      "peerDependencies": {
        "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
      },
      "peerDependenciesMeta": {
        "rollup": {
          "optional": true
        }
      }
    },
    "node_modules/@rollup/rollup-android-arm-eabi": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
      "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
      "cpu": [
        "arm"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "android"
      ]
    },
    "node_modules/@rollup/rollup-android-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
      "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
      "cpu": [
        "arm64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "android"
      ]
    },
    "node_modules/@rollup/rollup-darwin-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
      "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
      "cpu": [
        "arm64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "darwin"
      ]
    },
    "node_modules/@rollup/rollup-darwin-x64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
      "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
      "cpu": [
        "x64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "darwin"
      ]
    },
    "node_modules/@rollup/rollup-freebsd-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
      "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
      "cpu": [
        "arm64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "freebsd"
      ]
    },
    "node_modules/@rollup/rollup-freebsd-x64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
      "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
      "cpu": [
        "x64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "freebsd"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
      "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
      "cpu": [
        "arm"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
      "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
      "cpu": [
        "arm"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
      "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
      "cpu": [
        "arm64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm64-musl": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
      "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
      "cpu": [
        "arm64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
      "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
      "cpu": [
        "loong64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
      "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
      "cpu": [
        "ppc64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
      "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
      "cpu": [
        "riscv64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-s390x-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
      "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
      "cpu": [
        "s390x"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-x64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
      "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
      "cpu": [
        "x64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-x64-musl": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
      "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
      "cpu": [
        "x64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-win32-arm64-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
      "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
      "cpu": [
        "arm64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "win32"
      ]
    },
    "node_modules/@rollup/rollup-win32-ia32-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
      "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
      "cpu": [
        "ia32"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "win32"
      ]
    },
    "node_modules/@rollup/rollup-win32-x64-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
      "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
      "cpu": [
        "x64"
      ],
      "license": "MIT",
      "optional": true,
      "os": [
        "win32"
      ]
    },
    "node_modules/@types/estree": {
      "version": "1.0.9",
      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
      "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
      "license": "MIT"
    },
    "node_modules/commondir": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
      "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
      "license": "MIT"
    },
    "node_modules/estree-walker": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
      "license": "MIT"
    },
    "node_modules/fdir": {
      "version": "6.5.0",
      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
      "license": "MIT",
      "engines": {
        "node": ">=12.0.0"
      },
      "peerDependencies": {
        "picomatch": "^3 || ^4"
      },
      "peerDependenciesMeta": {
        "picomatch": {
          "optional": true
        }
      }
    },
    "node_modules/fsevents": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
      "hasInstallScript": true,
      "license": "MIT",
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
      }
    },
    "node_modules/is-reference": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
      "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
      "license": "MIT",
      "dependencies": {
        "@types/estree": "*"
      }
    },
    "node_modules/magic-string": {
      "version": "0.30.21",
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
      "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
      "license": "MIT",
      "dependencies": {
        "@jridgewell/sourcemap-codec": "^1.5.5"
      }
    },
    "node_modules/picomatch": {
      "version": "4.0.7",
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
      "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
      "license": "MIT",
      "engines": {
        "node": ">=12"
      },
      "funding": {
        "url": "https://github.com/sponsors/jonschlinkert"
      }
    },
    "node_modules/rollup": {
      "version": "4.34.8",
      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz",
      "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
      "license": "MIT",
      "dependencies": {
        "@types/estree": "1.0.6"
      },
      "bin": {
        "rollup": "dist/bin/rollup"
      },
      "engines": {
        "node": ">=18.0.0",
        "npm": ">=8.0.0"
      },
      "optionalDependencies": {
        "@rollup/rollup-android-arm-eabi": "4.34.8",
        "@rollup/rollup-android-arm64": "4.34.8",
        "@rollup/rollup-darwin-arm64": "4.34.8",
        "@rollup/rollup-darwin-x64": "4.34.8",
        "@rollup/rollup-freebsd-arm64": "4.34.8",
        "@rollup/rollup-freebsd-x64": "4.34.8",
        "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
        "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
        "@rollup/rollup-linux-arm64-gnu": "4.34.8",
        "@rollup/rollup-linux-arm64-musl": "4.34.8",
        "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
        "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
        "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
        "@rollup/rollup-linux-s390x-gnu": "4.34.8",
        "@rollup/rollup-linux-x64-gnu": "4.34.8",
        "@rollup/rollup-linux-x64-musl": "4.34.8",
        "@rollup/rollup-win32-arm64-msvc": "4.34.8",
        "@rollup/rollup-win32-ia32-msvc": "4.34.8",
        "@rollup/rollup-win32-x64-msvc": "4.34.8",
        "fsevents": "~2.3.2"
      }
    },
    "node_modules/rollup/node_modules/@types/estree": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
      "license": "MIT"
    }
  }
}
package.json
{
  "name": "npm-rollup-plugin-commonjs-esm-externals",
  "version": "1.0.0",
  "license": "MIT-0",
  "type": "module",
  "scripts": {
    "test": "node test/contract.mjs"
  },
  "dependencies": {
    "@rollup/plugin-commonjs": "28.0.7",
    "rollup": "4.34.8"
  }
}
spec.json
{
  "schemaVersion": 1,
  "goal": "By default @rollup/plugin-commonjs renders external requires as default imports causing named exports to be inaccessible unless esmExternals is configured",
  "kind": "HOW",
  "packages": [
    "pkg:npm/%40rollup/plugin-commonjs@28.0.7",
    "pkg:npm/rollup@4.34.8"
  ],
  "symbols": [
    "commonjs",
    "esmExternals"
  ]
}
test/contract.mjs
import assert from 'node:assert/strict';
import { rollup } from 'rollup';
import commonjs from '@rollup/plugin-commonjs';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');

async function runContract() {
  const mockModuleDir = path.join(projectRoot, 'node_modules', 'mock-external-esm');
  fs.mkdirSync(mockModuleDir, { recursive: true });
  fs.writeFileSync(
    path.join(mockModuleDir, 'package.json'),
    JSON.stringify({
      name: 'mock-external-esm',
      version: '1.0.0',
      type: 'module',
      exports: './index.js'
    })
  );
  fs.writeFileSync(
    path.join(mockModuleDir, 'index.js'),
    `export const version = '1.0.0';
export const helper = function() { return 'helped'; };
export default { defaultKey: 'defaultValue' };`
  );

  const mockOtherDir = path.join(projectRoot, 'node_modules', 'mock-other-pkg');
  fs.mkdirSync(mockOtherDir, { recursive: true });
  fs.writeFileSync(
    path.join(mockOtherDir, 'package.json'),
    JSON.stringify({
      name: 'mock-other-pkg',
      version: '1.0.0',
      main: './index.js'
    })
  );
  fs.writeFileSync(
    path.join(mockOtherDir, 'index.js'),
    `module.exports = { otherVal: 'from-other-cjs' };`
  );

  const virtualEntry = {
    name: 'virtual-entry',
    resolveId(id) {
      if (id === 'entry-cjs.cjs') return id;
    },
    load(id) {
      if (id === 'entry-cjs.cjs') {
        return `
const ext = require('mock-external-esm');
const other = require('mock-other-pkg');
module.exports = { ext, other };
`;
      }
    }
  };

  const tmpFiles = [];

  try {
    // -------------------------------------------------------------------------
    // Contract Assertion 1:
    // By default (esmExternals: false), @rollup/plugin-commonjs treats external
    // dependencies as CommonJS default imports, causing named exports from
    // external ES modules to be inaccessible (undefined) when required from CommonJS.
    // -------------------------------------------------------------------------
    const defaultBundle = await rollup({
      input: 'entry-cjs.cjs',
      external: ['mock-external-esm', 'mock-other-pkg'],
      plugins: [virtualEntry, commonjs()]
    });
    const { output: defaultOutput } = await defaultBundle.generate({ format: 'es' });
    const defaultCode = defaultOutput[0].code;

    assert.match(
      defaultCode,
      /import\s+require\$\$\d+\s+from\s+['"]mock-external-esm['"];/,
      'assert @rollup/plugin-commonjs with default esmExternals: false emits default imports for external dependencies, causing named exports to be inaccessible (undefined) when required from CommonJS'
    );

    const tmpDefault = path.join(projectRoot, '.tmp-contract-default.mjs');
    tmpFiles.push(tmpDefault);
    fs.writeFileSync(tmpDefault, defaultCode);
    const modDefault = (await import(`file://${tmpDefault.replace(/\\/g, '/')}`)).default;

    assert.equal(
      typeof modDefault.ext.helper,
      'undefined',
      'Named export is undefined when required from CommonJS under default esmExternals: false'
    );
    assert.equal(
      modDefault.ext.defaultKey,
      'defaultValue',
      'Default export remains accessible through default import proxy'
    );

    // -------------------------------------------------------------------------
    // Contract Assertion 2:
    // Setting esmExternals: true renders external dependencies as namespace
    // imports wrapped in an augmented namespace, exposing both named and default exports.
    // -------------------------------------------------------------------------
    const esmBundle = await rollup({
      input: 'entry-cjs.cjs',
      external: ['mock-external-esm', 'mock-other-pkg'],
      plugins: [virtualEntry, commonjs({ esmExternals: true })]
    });
    const { output: esmOutput } = await esmBundle.generate({ format: 'es' });
    const esmCode = esmOutput[0].code;

    assert.match(
      esmCode,
      /import\s+\*\s+as\s+mockExternalEsm\s+from\s+['"]mock-external-esm['"];/,
      'assert setting esmExternals: true emits namespace imports for external dependencies, creating an augmented namespace that exposes both named exports and default export'
    );

    const tmpEsm = path.join(projectRoot, '.tmp-contract-esm.mjs');
    tmpFiles.push(tmpEsm);
    fs.writeFileSync(tmpEsm, esmCode);
    const modEsm = (await import(`file://${tmpEsm.replace(/\\/g, '/')}`)).default;

    assert.equal(
      typeof modEsm.ext.helper,
      'function',
      'Named exports are accessible from augmented namespace when esmExternals is true'
    );
    assert.equal(modEsm.ext.helper(), 'helped');
    assert.equal(modEsm.ext.version, '1.0.0');
    assert.deepEqual(modEsm.ext.default, { defaultKey: 'defaultValue' });

    // -------------------------------------------------------------------------
    // Contract Assertion 3:
    // esmExternals accepts an array of package IDs to selectively emit namespace
    // imports for specified ESM dependencies while leaving other externals as default imports.
    // -------------------------------------------------------------------------
    const selectiveBundle = await rollup({
      input: 'entry-cjs.cjs',
      external: ['mock-external-esm', 'mock-other-pkg'],
      plugins: [virtualEntry, commonjs({ esmExternals: ['mock-external-esm'] })]
    });
    const { output: selectiveOutput } = await selectiveBundle.generate({ format: 'es' });
    const selectiveCode = selectiveOutput[0].code;

    assert.match(
      selectiveCode,
      /import\s+\*\s+as\s+mockExternalEsm\s+from\s+['"]mock-external-esm['"];/,
      'assert esmExternals accepts an array of package IDs to selectively emit namespace imports for specified ESM dependencies while leaving other externals as default imports'
    );
    assert.match(
      selectiveCode,
      /import\s+require\$\$\d+\s+from\s+['"]mock-other-pkg['"];/,
      'Non-targeted external module remains a default import'
    );

    // -------------------------------------------------------------------------
    // Contract Assertion 4:
    // esmExternals accepts a predicate function to dynamically determine which
    // external dependencies are imported as ES module namespaces.
    // -------------------------------------------------------------------------
    const fnBundle = await rollup({
      input: 'entry-cjs.cjs',
      external: ['mock-external-esm', 'mock-other-pkg'],
      plugins: [
        virtualEntry,
        commonjs({
          esmExternals: (id) => id.includes('external-esm')
        })
      ]
    });
    const { output: fnOutput } = await fnBundle.generate({ format: 'es' });
    const fnCode = fnOutput[0].code;

    assert.match(
      fnCode,
      /import\s+\*\s+as\s+mockExternalEsm\s+from\s+['"]mock-external-esm['"];/,
      'assert esmExternals accepts a predicate function to dynamically determine which external dependencies are imported as ES module namespaces'
    );
    assert.match(
      fnCode,
      /import\s+require\$\$\d+\s+from\s+['"]mock-other-pkg['"];/,
      'Predicate returning false renders default import'
    );

    console.log('All contract assertions passed successfully.');
  } finally {
    for (const f of tmpFiles) {
      if (fs.existsSync(f)) {
        fs.unlinkSync(f);
      }
    }
    if (fs.existsSync(mockModuleDir)) {
      fs.rmSync(mockModuleDir, { recursive: true, force: true });
    }
    if (fs.existsSync(mockOtherDir)) {
      fs.rmSync(mockOtherDir, { recursive: true, force: true });
    }
  }
}

runContract().catch((err) => {
  console.error('Contract failed:', err);
  process.exit(1);
});

Seeder d'origine

anonyme