node-csvtojson
node-csvtojson copied to clipboard
Optimize usage with bundlers
I'm using csvtojson
in the browser, and I'm interested in optimizing this library's usage with bundlers (webpack, rollup, etc). There's a few areas for opportunity:
- When you bundle
csvtojson
with Webpack, by default, Webpack points to thebrowser
mainField. This build has an inlined copy of Buffer. Webpack will already inline Buffer for you -- and I have other projects that also need it. Therefore, I end up with two copies of Buffer in my module. - To workaround the duplicate Buffer copy, I've modified my webpack configuration to use the
main
field. However, the v2 implementation uses Bluebird. Currently, I'm using core-js to polyfill Promises. So, I end up with two Promise polyfills -- Bluebird and core-js's.
There are a couple potential approaches for optimizing usage with bundlers:
-
Switch from Bluebird to native Promises. Users configure their bundlers to use the
main
field ofcsvtojson
.- This allows users with bundlers the freedom to choose whichever Promise polyfill they prefer.
-
Provide an ES Module build of this library, and a
module
field to package.json.- This could be done along side with Number 1, but isn't strictly necessary.
- In tsconfig.json, the importHelpers can be enabled to prevent utility functions like these from being inlined.
-
Scrap providing the Buffer polyfill in the
browser
build.- This is probably a no-go, since people could be using this build without bundlers.
@Keyang Please provide guidance for which of these options sound best for improving this package's usage with bundlers, and I can begin work on a pull request. These changes would significantly reduce the bundle size of csvtojson when used in the browser, which is 165 kB minified. Thanks!
@petermikitsh , Thanks for the feedback. For browser support, there are 2 ways: 1. use bundlers like webpack; 2. import from script tag directly. Please make sure any changes you have made will support both.
Others:
- I think the "browser" field was wrong initially. As you pointed out, it should be the same as main field.
- The
browser.js
andcsvtojson.min.js
are browser version for script tag import. Please make sure those files are still available after changing. - The reason of using
BlueBird
was it being way faster than native Promise. I do not know if it is still the case in 2019. Could you please do some research on this? - a
module
field in package.json should be okay. - enable
importHelpers
is a good idea - Scrap providing the Buffer polyfill in the browser build. -- agreed that it may still be needed. so please keep the backward compatibility.
Really good work to push csvtojson to browser. As you said, there are lots to optimize to reduce the bundle size. Thanks.
Thank you for the quick reply. I have enough information work to proceed on a PR. I did more research on Number 3:
Bluebird's homepage has this to say on Bluebird vs. Native Promise performance:
"Promises in Node.js 10 are significantly faster than before. Bluebird still includes a lot of features like cancellation, iteration methods and warnings that native promises don't. If you are using Bluebird for performance rather than for those - please consider giving native promises a shot and running the benchmarks yourself."
In the browser, both implementations have nearly identical performance.
I think it would be a fair statement to say that the landscape for Promises has changed. csvbench could assist with verifying no performance degradation when experimenting with native Promises.
Thanks. Please give a try with native promise and other updates. As csvtojson supporting node 4+ thus if we want to switch to native promise, we do need a way to allow users to swap Promise library to use for performance and backward compatibility.