-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v3: consider changing export logic for esm modules #7371
Comments
I would love to make Chart.js tree-shakeable We had investigated a bit earlier. Some notes:
@sgratzl any chance you would want to implement this? :-) We're all pretty busy and haven't had much time for core development lately, but we could talk and decide that last point if someone has the time to implement it |
Some quick opinions:
|
I am in favour of the string API if possible. I think its a better default out of the box since it's backwards compatible with v2 code and also quite easy to understand. It also doesn't break any existing documentation that's out there on SO or equivalent. If we can do an opt-in tree shaking API initially, I am on-board. That would let us experiment and see what works well and then consider how to migrate all users to it eventually. |
Ok, I think basically all we need to do is:
|
I think the biggest side effect in the library are the defaults. e.g., while elements don't need to be registered their defaults need to be, Thus creating a side effect. One approach could be using the same idea as in the scale case ->static in https://github.com/sgratzl/chartjs-chart-boxplot/tree/develop I adapted the plugin to support tree shaking as good as possible. Essential changes:
|
I would prefer a function per type. it is easier to ensure that the right arguments are given and one can avoid conflicts in names. e.g. a
I have a
in the best case, chart.js supports two options everywhere where a
relevant locations as far as I can see:
|
If we had one method it could check the type (e.g. is it a subclass of
That sounds good to me
We actually only need the constructor. At least that's how scale registration works now. The id is a static property on the constructor
We had discussed this as an option earlier, but I think the consensus was to only support the |
I played a bit with tree shaking by manually commenting out things from the build that are not needed for a bar chart and then use rollup to remove all the things that fall of. see https://github.com/sgratzl/chartjs-treeshake-test. in summary:
it could be a bit less if the besides removing all the wrappers (elements, plugins, scales, ...) I mostly had to comment out access of the prototypes (e.g., |
Wow, that's great! I'm a little surprised that not more was able to be shaken out, but it's a good start. No one will complain about a 30% reduction in build size! If you want to send us any PRs to make these changes we'd be happy to review. (btw, I didn't understand what you meant about wrappers) Code tends to shake out better when it's functions. We use a lot of classes and those don't shake out well, so I guess that's the core issue. I think there are some additional wins we can get by updating things a bit. E.g. one I noticed is that the whole color library is getting pulled in and we don't need most of it. We really just use Another thing I noticed is that your build had the |
the main question I wonder is how to deal with detault values. e.g. all the
one could consider switching to a different library such as d3-color or tinycolor. regarding custom parsing, it would require that uses can manipulate the interpolators or the automatic hover color.
if you take a look at https://unpkg.com/[email protected]/dist/Chart.esm.js?module it is part of your esm build. maybe babel injects it because of your browserlist settings. |
https://www.chartjs.org/dist/master/Chart.esm.js does not contain it anymore. |
Maybe apply the defaults when registering the controller / element. Part of the class prototype? Not sure where the best location to ship those is. |
It looks like just the legend has that issue. We had at one point talked about removing the element options. Regardless though, I would be open to giving the legend its own defaults instead of using
That sounds good to me.
@sgratzl had said earlier "I mostly had to comment out access of the prototypes (e.g., LineController.prototype.dataElementOptions = ...). [They prevent the] LineController from being shaken since it is actually used". I'm not sure if there's a better way to do this. Does it work if we make them static fields? |
I have seen that most imports are leaving out the file extension. While this is fine for webpack/rollup or any other bundler that tries out some extension etc. in their resolver logic, this won't work for direct node or browser imports. See https://nodejs.org/api/esm.html#esm_mandatory_file_extensions, "Mandatory file extensions". |
I'm not sure why this is relevant, we are using rollup and babel to transpile the stuff before publishing it to npm. |
one general point which there needs to be a consensus about before continuing: There are two common ways how to deal with tree-shaking:
The separted case can be extended to also support the flat case but requires to have the pros/cons
|
Maybe those (dataElementOptions / datasetElementOptions) should also be part of the registration process. Edit: The |
I wouldn't say that you have to choose between either a single bundle file or direct delivery of the source files, but you could do both. I'm not sure how common this is yet, but I see it with most of the modules we work with (VueJS, Vuetify, ...). Taking a note from #7400
Importing the source files directly from a CDN via I wouldn't say that a (single-file) bundle is an old artifact, now that JS is capable of module-support, but I see its main use only in supporting old browsers that are incapable of In addition, users who use their own Webpack/Rollup/... bundle-process have also no need for a pre-bundled version, regardless which NodeJS version they are using or which browsers they want to support. In summary, it would be great if both could be supported (adding the source folder to the npm package and using the full file name in the imports). |
what about splitting up this issue, this one contains the discussion about how to structure the ESM build and another one about how to do the registration process for different components: controller, scales, elements, plugins |
@sgratzl ready to close this one? |
it would be nice if the logic and methods of this code block is generalized and also available in the ESM build: Lines 28 to 38 in 426d8de
|
Hi 😃 ! Just curious, do you have an approximate release "date/month" for tree-shaking? (I guess it's on your spare time, but just curious if any). Thank you, |
any day now |
Yes, we're quite close. Barring any last minute issues, we'll probably do the v3.0.0-alpha.2 release tonight or tomorrow |
Separating the helpers in the ESM build has broken |
I've sent fixes for the date adapters: In the meantime, you can avoid any issues by supplying timestamps and setting |
@sgratzl are there any more changes, you'd like to the export logic of v3? |
no, looking great, thx to all for all the effort |
Feature Proposal
the in the v3 version the enhanced Chart module is exported as the solely (default) export from the library.
https://github.com/chartjs/Chart.js/blob/master/src/index.js
As an alternative one could have the following structure:
the purpose around the Chart class is that only the default export has all the dependencies but not the class itself.
Feature Use Case
I want to prepare for tree shaking and thus only import things that I really need. e.g.,
note: while this works already with some synthetic imports (by rollup, ...) it is not standard conform.
Possible Implementation
The text was updated successfully, but these errors were encountered: