-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Rollup Version
v4.18.0
Operating System (or Browser)
macOS
Node Version (if applicable)
20.11.0
Link To Reproduction
Expected Behaviour
Specifying sideEffects in package.json should indicate that the specified files contain side effects, and thus should not be removed during tree-shaking.
Actual Behaviour
Specifying sideEffects in package.json seems to have the opposite of the desired effect, causing Rollup to remove the code during tree-shaking.
This example is a reduction of a real-world issue with Rollup bundling Observable Plot.
In Observable Plot, there is a complex relationship between the global plot function and the Mark class. To avoid circular imports between mark.js and plot.js (and many other files), mutation is used to assign Mark.prototype.plot:
This solitary side effect is declared in Plot’s package.json:
However, the sideEffects hint seems to have the opposite of the desired effect: the presence of the sideEffects hint causes Rollup to drop the assignment of Mark.prototype.plot rather than to include it!
To demonstrate this, I have made a minimal reproduction in the above git repository. The test-plot module consists of four simple JavaScript files:
plot.js
import {Mark} from "./mark.js";
export function plot({marks = []} = {}) {
return `plot(${marks})`;
}
Mark.prototype.plot = function () {
return plot({marks: [this]});
};mark.js
export class Mark {
toString() {
return "Mark";
}
}dot.js
import {Mark} from "./mark.js";
export class Dot extends Mark {
toString() {
return "Dot";
}
}index.js
export {plot} from "./plot.js";
export {Mark} from "./mark.js";
export {Dot} from "./dot.js";When the sideEffects hint is include in test-plot’s package.json, the resulting bundle looks like this:
class Mark {
toString() {
return "Mark";
}
}
class Dot extends Mark {
toString() {
return "Dot";
}
}
const dot = new Dot();
console.log(dot.plot());As you can see, the Mark.prototype.plot method is missing, and thus the code crashes. If the sideEffects hint is removed and the code is re-built like so:
yarn install --force && yarn test
Then the bundle changes to the expected output:
class Mark {
toString() {
return "Mark";
}
}
function plot({marks = []} = {}) {
return `plot(${marks})`;
}
Mark.prototype.plot = function () {
return plot({marks: [this]});
};
class Dot extends Mark {
toString() {
return "Dot";
}
}
const dot = new Dot();
console.log(dot.plot());