问题
I've got a file d3.custom.build.js
like this (simplified):
import { range } from 'd3-array';
import { select, selectAll, event } from 'd3-selection';
import { transition } from 'd3-transition';
export default {
range,
select,
selectAll,
event,
transition
};
And a rollup.config.js
like this:
import nodeResolve from 'rollup-plugin-node-resolve';
export default {
entry: './js/vendor/d3-custom-build.js',
dest: './js/vendor/d3-custom-built.js',
format: 'iife',
globals: {
d3: 'd3'
},
moduleId: 'd3',
moduleName: 'd3',
plugins: [nodeResolve({ jsnext: true })]
};
I want to export to a plain old browser global named 'd3'. I'm calling rollup from a simple npm script. The good news is that almost everything works in the output file, except for one thing: d3.event
in browser is always null. No, it's not an issue with events being hijacked on the page. When I swap in the standard full d3 4.0 library into the script tag everything works fine. It's definitely a build issue.
The d3 docs warn that bundling event
is tricky:
If you use Babel, Webpack, or another ES6-to-ES5 bundler, be aware that the value of d3.event changes during an event! An import of d3.event must be a live binding, so you may need to configure the bundler to import from D3’s ES6 modules rather than from the generated UMD bundle; not all bundlers observe jsnext:main. Also beware of conflicts with the window.event global.
It appears that setting nodeResolve({ jsnext: true })
isn't sufficing. How do I get a live binding in the bundle? Any guidance very appreciated.
回答1:
You’re exporting an object, defined using ES2015 shorthand object literal syntax, as the default export. Here is the long form equivalent of what you’ve written:
export default {
range: range,
select: select,
selectAll: selectAll,
event: event,
transition: transition
}
Your object thus captures the value of event
on load, which is null; it is not a live binding, and won’t reflect the current event.
One fix would be to define the event
property using a getter:
export default {
range,
select,
selectAll,
get event() { return event; },
transition
}
Better would be to use named exports instead of a default export, and then Rollup will generate a live binding automatically:
export {
range,
select,
selectAll,
event,
transition
}
This is not only shorter, but now you don’t depend on the browser supporting the ES2015 shorthand object literal syntax.
来源:https://stackoverflow.com/questions/40012016/importing-d3-event-into-a-custom-build-using-rollup