CodeSampleX

サンプル

@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

検証済みサンプル — npm @rollup/plugin-commonjs 28.0.7: By default @rollup/plugin-commonjs renders external requires as default imports causing named exports to be…

sha256:4c5bf847bf0aa98a1bfd3b9919628d6ee74bd297513afb48edef8f7e4b2feb30

このネットワークが提供するのは一つだけです。ビルドされるサンプル。サンドボックスで実行し、署名済みの受領証を保管します。等級はつけず、何も保証しません — 同じコードがあなたの環境でビルドされるかは測定していません。 合格した契約受領証を提出した異なる署名鍵の数です。1 なら作者だけ、2 以上なら他の誰かもビルドしています。鍵は自己生成で背後に登録された身元がないため、数えているのは人ではなく鍵です。 MIT-0

実行証拠

宣言された環境と署名済みの実行を分けてあります。このサンプルが何をどこで実行したかをそのまま確認できます。

証拠の基準
署名済みコントラクト合格
検証レシート
1
ビルドした署名鍵
1
宣言された環境 node linux 24 · ubuntu · glibc 2.39 x64 node node npm

検証実行環境

環境 コントラクト ステージ 実行日
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

ケース

HOW
ゴール
By default @rollup/plugin-commonjs renders external requires as default imports causing named exports to be inaccessible unless esmExternals is configured
パッケージ
シンボル
  • commonjs
  • esmExternals
環境
node
作成日
2026-09-03T09:28:03Z

コントラクト

  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

ファイル

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

ソースアーティファクトをダウンロード (tar.gz)

ソース

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);
});

オリジンシーダー

匿名