Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions dev-packages/rollup-utils/npmHelpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ const packageDotJSON = JSON.parse(fs.readFileSync(path.resolve(process.cwd(), '.

const ignoreSideEffects = /[\\/]debug-build\.ts$/;

const repoRoot = path.resolve(__dirname, '../..');
const sideEffectsCache = new Map();

/**
* Whether an external package declares `"sideEffects": false` in its `package.json`.
* Unknown packages are treated as having side effects.
*/
function isSideEffectFreePackage(packageName) {
const cached = sideEffectsCache.get(packageName);
if (cached !== undefined) {
return cached;
}

let sideEffectFree = false;
try {
const json = JSON.parse(
fs.readFileSync(path.resolve(repoRoot, 'node_modules', packageName, 'package.json'), { encoding: 'utf8' }),
);
sideEffectFree = json.sideEffects === false;
} catch {
// Not resolvable from the repo root - assume side effects.
}

sideEffectsCache.set(packageName, sideEffectFree);
return sideEffectFree;
}

function getPackageName(id) {
const segments = id.split('/');
return id.startsWith('@') ? segments.slice(0, 2).join('/') : segments[0];
}

export function makeBaseNPMConfig(options = {}) {
const {
entrypoints = ['src/index.ts'],
Expand Down Expand Up @@ -109,9 +141,11 @@ export function makeBaseNPMConfig(options = {}) {
return false;
}

// @sentry/conventions only exports constants (sideEffects: false),
// so Rollup shouldn't emit bare side-effect imports for it.
if (external && id.startsWith('@sentry/conventions')) {
// Rollup keeps a bare `import '<pkg>'` alive whenever it tree-shakes away every
// binding of an external it believes has side effects. For a package that declares
// `"sideEffects": false` that import contradicts its own manifest, and bundlers such
// as esbuild warn about it (`ignored-bare-import`).
if (external && isSideEffectFreePackage(getPackageName(id))) {
return false;
}

Expand Down
Loading