CodeSampleX

示例

rollup 4.34.8: Configuring treeshake.moduleSideEffects to false silently removes bare side-effect imports lacking consumed bindings, whereas setting it to 'no-external' preserves internal side-effect modules while pruning external ones.

已验证示例 — npm rollup 4.34.8: Configuring treeshake.moduleSideEffects to false silently removes bare side-effect imports lacking consumed bindings, whereas…

sha256:92601fd5622eb4523c4c39713473c67395bc60dbed071830173bede138b89a13

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 MIT-0

执行证据

声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。

证据依据
签名契约通过
验证回执
2
构建过它的签名密钥
2
声明的环境 node linux x64 node node npm

验证运行环境

环境 契约 阶段 运行日期
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-17
node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18

案例

HOW
目标
Configuring treeshake.moduleSideEffects to false silently removes bare side-effect imports lacking consumed bindings, whereas setting it to 'no-external' preserves internal side-effect modules while pruning external ones.
包
符号
  • rollup.rollup
环境
node
创建时间
2026-08-17T11:12:35Z

契约

  1. Setting treeshake: { moduleSideEffects: false } causes Rollup to strip bare side-effect imports that have no consumed exports, whereas treeshake: { moduleSideEffects: 'no-external' } retains internal side-effect imports and strips unused external ones.
  2. Executing a bundle built with moduleSideEffects: false leaves global state uninitialized by the stripped polyfill, while executing a bundle built with moduleSideEffects: 'no-external' triggers the top-level side effects on module load.
  3. Default tree-shaking (moduleSideEffects: true) retains both internal and external side-effect imports unconditionally.

文件

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

下载源代码构件 (tar.gz)

源代码

NOTES.md
# Rollup Module Side Effects Configuration

## Prior Solutions Query

A search for prior solutions returned COMPATIBLE samples covering other aspects of Rollup bundling:
- Sample `7844de612517f8f5156daa2f0a6282d39d3510ccb3784110a987ff5a430d5353`: Loading legacy JavaScript configuration and plugins in `@tailwindcss/postcss` using `@config`.
- Sample `cc855f6e2ffb27e94ec04022420e396e18e35039cb52005f67985f9a7f0aab0c`: Showing strict wrapping does not hoist conditional external node builtins into emitted CJS.
- Sample `6bd9e4aeb00bbe86cb0245f6c6955ae8ec7421dba24da3b8401f6307646e0ad8`: Marking CommonJS dependencies as external silently breaking default imports without `output.interop: 'auto'`.

None of the existing samples investigated the behavior of `treeshake.moduleSideEffects` on bare side-effect imports.

## Pinned Release

- `rollup`: `4.34.8`

## Observed Behavior

When bundling JavaScript code with `treeshake: { moduleSideEffects: false }`:
- Rollup assumes that no module contains side effects unless an exported symbol is referenced and consumed by another module.
- Bare side-effect imports (such as `import './internal-polyfill.js'` or `import 'external-side-effect'`), which export nothing or whose exports are unreferenced, are completely stripped from the final bundle output.
- The build succeeds without warnings or errors (a green build), but at runtime, the expected side effects (such as global object mutations, polyfill registrations, or CSS imports) are never executed.

When configured with `treeshake: { moduleSideEffects: 'no-external' }`:
- Internal relative imports (non-external) with side effects are preserved in the bundle, while unused external side-effect packages are stripped.

When configured with the default setting (`treeshake: { moduleSideEffects: true }` or `treeshake: true`):
- Both internal and external side-effect imports are preserved unconditionally.

## Failure Mode

The incorrect assumption that bare `import './file.js'` statements are inherently immune to tree-shaking fails **silently with a green build**. Rollup bundles and writes output cleanly without throwing errors, but polyfills, telemetry initializers, or global configuration hooks are omitted from the emitted artifact.
csx.json
{"case":{"believed":"A bare import with no specifiers, such as import './polyfill.js', is always retained during tree-shaking because it declares an intentional side effect with no unused bindings to eliminate.","caseId":"case:sha256:fc9e7a95e6f5b6aec7a69aa48fffc00349e153d8a623d0339f35cefb01db3985","contract":["Setting treeshake: { moduleSideEffects: false } causes Rollup to strip bare side-effect imports that have no consumed exports, whereas treeshake: { moduleSideEffects: 'no-external' } retains internal side-effect imports and strips unused external ones.","Executing a bundle built with moduleSideEffects: false leaves global state uninitialized by the stripped polyfill, while executing a bundle built with moduleSideEffects: 'no-external' triggers the top-level side effects on module load.","Default tree-shaking (moduleSideEffects: true) retains both internal and external side-effect imports unconditionally."],"goal":"Configuring treeshake.moduleSideEffects to false silently removes bare side-effect imports lacking consumed bindings, whereas setting it to 'no-external' preserves internal side-effect modules while pruning external ones.","kind":"HOW","packages":["pkg:npm/rollup@4.34.8"],"schemaVersion":1,"symbols":["rollup.rollup"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/rollup@4.34.8"],"schemaVersion":1,"symbols":["rollup.rollup"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "npm-rollup-config",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "npm-rollup-config",
      "version": "1.0.0",
      "dependencies": {
        "rollup": "4.34.8"
      }
    },
    "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.6",
      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
      "license": "MIT"
    },
    "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/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"
      }
    }
  }
}
package.json
{
  "name": "npm-rollup-config",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "dependencies": {
    "rollup": "4.34.8"
  }
}
test/contract.mjs
import assert from 'node:assert/strict';
import { rollup } from 'rollup';

// In-memory plugin providing mock modules for testing tree-shaking configuration
function virtualModulesPlugin() {
  const modules = {
    'entry.js': `
      import './internal-polyfill.js';
      import 'external-side-effect';
      import { calculate } from './calc.js';
      export const answer = calculate(20, 22);
    `,
    'internal-polyfill.js': `
      globalThis.__INTERNAL_POLYFILL_LOADED__ = true;
    `,
    'calc.js': `
      export function calculate(a, b) {
        return a + b;
      }
    `,
  };

  return {
    name: 'test-virtual-modules',
    resolveId(id) {
      if (id === 'entry.js' || id === 'internal-polyfill.js' || id === 'calc.js') {
        return id;
      }
      if (id === './internal-polyfill.js') {
        return 'internal-polyfill.js';
      }
      if (id === './calc.js') {
        return 'calc.js';
      }
      return null;
    },
    load(id) {
      return modules[id] ?? null;
    },
  };
}

async function run() {
  // Case 1: treeshake.moduleSideEffects: false
  // Proves that bare side-effect imports are completely discarded when no exports are consumed.
  const bundleFalse = await rollup({
    input: 'entry.js',
    plugins: [virtualModulesPlugin()],
    external: ['external-side-effect'],
    treeshake: { moduleSideEffects: false },
  });
  const { output: [outputFalse] } = await bundleFalse.generate({ format: 'cjs' });

  // The output does NOT contain the internal polyfill side-effect code
  assert.ok(
    !outputFalse.code.includes('__INTERNAL_POLYFILL_LOADED__'),
    'moduleSideEffects: false must strip internal side-effect-only modules'
  );
  // The output does NOT contain the external side-effect import
  assert.ok(
    !outputFalse.code.includes('external-side-effect'),
    'moduleSideEffects: false must strip external side-effect imports'
  );

  // Runtime evaluation of the bundle with moduleSideEffects: false
  globalThis.__INTERNAL_POLYFILL_LOADED__ = false;
  const cjsExportsFalse = {};
  const fnFalse = new Function('exports', 'require', outputFalse.code);
  fnFalse(cjsExportsFalse, () => ({}));
  assert.strictEqual(cjsExportsFalse.answer, 42);
  assert.strictEqual(
    globalThis.__INTERNAL_POLYFILL_LOADED__,
    false,
    'Internal polyfill must NOT have executed because it was tree-shaken away'
  );

  // Case 2: treeshake.moduleSideEffects: 'no-external'
  // Proves that internal side-effect modules are retained while unused external imports are dropped.
  const bundleNoExternal = await rollup({
    input: 'entry.js',
    plugins: [virtualModulesPlugin()],
    external: ['external-side-effect'],
    treeshake: { moduleSideEffects: 'no-external' },
  });
  const { output: [outputNoExternal] } = await bundleNoExternal.generate({ format: 'cjs' });

  // Internal polyfill IS included
  assert.ok(
    outputNoExternal.code.includes('__INTERNAL_POLYFILL_LOADED__'),
    'moduleSideEffects: "no-external" must preserve internal side-effect modules'
  );
  // External side-effect import is still stripped
  assert.ok(
    !outputNoExternal.code.includes('external-side-effect'),
    'moduleSideEffects: "no-external" must strip unused external side-effect imports'
  );

  // Runtime evaluation of the bundle with moduleSideEffects: 'no-external'
  globalThis.__INTERNAL_POLYFILL_LOADED__ = false;
  const cjsExportsNoExternal = {};
  const fnNoExternal = new Function('exports', 'require', outputNoExternal.code);
  fnNoExternal(cjsExportsNoExternal, () => ({}));
  assert.strictEqual(cjsExportsNoExternal.answer, 42);
  assert.strictEqual(
    globalThis.__INTERNAL_POLYFILL_LOADED__,
    true,
    'Internal polyfill must have executed on module evaluation'
  );

  // Case 3: treeshake.moduleSideEffects: true (default)
  // Proves that default tree-shaking preserves both internal and external side-effect imports.
  const bundleDefault = await rollup({
    input: 'entry.js',
    plugins: [virtualModulesPlugin()],
    external: ['external-side-effect'],
    treeshake: { moduleSideEffects: true },
  });
  const { output: [outputDefault] } = await bundleDefault.generate({ format: 'cjs' });

  assert.ok(
    outputDefault.code.includes('__INTERNAL_POLYFILL_LOADED__'),
    'Default moduleSideEffects must include internal side effects'
  );
  assert.ok(
    outputDefault.code.includes('external-side-effect'),
    'Default moduleSideEffects must include external side-effect imports'
  );
}

run();

原始种子者

csx-seed