-
Notifications
You must be signed in to change notification settings - Fork 335
Add an ESM build #414
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
Add an ESM build #414
Conversation
Awesome! Thanks for this! It looks like |
I think we agreed on not registering on any build to be consistent. |
After I asked yesterday about whether plugins should register, I remembered that the v3 migration guide says that Chart.js 3 itself doesn't require registering when it's imported via a So registering in the UMD build seems more consistent? (I'm happy to do whichever; I just wanted to confirm before proceeding.) |
The rationale behind this change in the datalabels plugin is detailed in chartjs/chartjs-plugin-datalabels#42.
Auto-registering should have nothing to do with the type of package, especially because UMD builds can be used with And when using |
Its not only about plugins though. If we want to be consistent the registration of controllers, elements and scales should be required in all builds too. and that would be silly in my opinion, because you can not shake anything from an umd build. unless we provide some generic |
It's not the same because registering a plugin makes it immediately active while registering a controller / element / scale does not. I think I would actually make registering core plugins required for all builds so it's fully consistent. And again, registering a plugin is not about tree-shaking but about making it "active" for all charts. The fact that there is a single |
I find extremely annoying, not intuitive and not user friendly the way to integrate Chart.js with the ESM build (which is nowadays the most common use case). I understand why "some" wants this granularity of import/register but "most" users should not have to deal with all these imports. For example, a user who wants to create a line chart should not have to think about registering the One solution could be to provide some kind of "presets" so "most" users would just have to: import { LineChart } from 'chart.js';
Chart.register(LineChart);
new Chart(ctx, {
type: 'line',
options,
data,
}); |
There are some such as pie where registration is probably unnecessarily verbose even for tree-shaking users - you can't have a pie / doughnut / polar area chart without radial scale and arc element, so perhaps we should automatically register those for you in that case. I kind of like the preset idea. LineController is one of the trickiest because it's pretty common not to use the default scales. E.g. the category scale is often switched out for linear or time/timeseries scale. Line/radar is also the only one with multiple possible elements. Registering both elements would make sense for the preset case. Would we register all compatible scales as well? And also all compatible plugins like the filler plugin? |
I think the idea of registering and enabling plugins has gotten a bit muddied. I think plugins should always be registered when imported (i.e. available for use), but should not be globally enabled by default in either the UMD or ESM builds. I think it's reasonable to have an API to globally enable, but we should not call it |
I disagree on this because it's usually not a good practice to expect side effect on import. Also, we could imagine a plugin that "overrides" another plugin, in which case we don't necessarily want the base plugin to be registered. For example: import DataLabels from 'chartjs-plugin-datalabels';
// chartjs-plugin-custom-datalabels
export default Object.assign({}, DataLabels , {
beforeUpdate() {
// ...
}
}); I would compare this to Vue.js and their official plugins: they recently chose to remove this side-effect logic in favor of explicit registration. I also think it's a better approach, at least for our plugins. And honestly, I'm not sure to understand what we are trying to simplify? import ZoomPlugin from 'chartjs-plugin-zoom';
Chart.plugins.register(ZoomPlugin); vs import 'chartjs-plugin-zoom'; // side-effect
Chart.plugins.enable('zoom'); The first snippet looks more predictable and robust IMO. |
@benmccann after reading again your comment, I'm wondering if I correctly understood your suggestion :) i.e. registering the plugin should be a side effect of importing the plugin or if we should expect the user to explicitly call |
I was suggesting to have a side effect, but to your point that's not really necessary to avoid verbosity. Maybe a better way to solve my concern without side effects is to rename the API. |
I agree with @simonbrunel that the first syntax is much more explicit, and it's a good practice to avoid side effects IMO. @benmccann Maybe a function named Chart.plugins.use(ZoomPlugin); |
I agree to this, the removal of auto-registration needs changes in test setup, so it should be done separately. |
Based off of chartjs-plugin-annotation's approach. Specific changes: - Switch from Gulp to Rollup for build; using Rollup directly works and seems simpler. - Refactor some duplicate configuration in rollup.config.js. - Change import style for Chart.js and Chart.js helpers so that it will work with modules. - The new import style doesn't allow adding to the imported object, which caused problems for the `Chart.Zoom` namespace. Since that namespace appears to be undocumented and unused, I removed it.
Use a named export instead of a default export. Don't automatically register the plugin for ESM builds. This matches chartjs-plugin-annotation and seems to better match Chart.js 3's tree-shaking design. I'm unclear on whether the UMD build should automatically register the plugin. Not registering seems to better match Chart.js 3, and chartjs-plugin-datalabels [recently changed][1] to no longer register, but chartjs-plugin-annotation does. [1]: <chartjs/chartjs-plugin-datalabels@13daa47>
Gulp copied compiled files to the project root. I don't see any reason to do this.
As suggested in code review. This also better matches the coding style in other Chart.js code.
Thanks for the discussion and feedback. I've rebased and responded to the remaining code review comments. Switching to an explicit use / register step makes sense to me, but as suggested by @kurkle, I preserved the existing behavior (UMD does auto-register) for now, to keep this PR more focused and to leave the tests unchanged. |
* Copy the files from `/dist` to the root directory. | ||
* @todo remove at version 1.0 | ||
*/ | ||
function copyDistFilesTask() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing this will break gulp package
so that the release process doesn't work. you might want to leave this but make it run as the first step of package
instead of the last step of build
@@ -9,5 +9,3 @@ coverage/* | |||
|
|||
nbproject/* | |||
dist/ | |||
chartjs-plugin-zoom.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should probably leave these and add the esm files as well for packaging. see my other comment below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding correctly, we don't need these .gitignore lines or the gulpfile copyDistFilesTask
.
The previous configuration invoked Rollup to put the files under dist
, then it called copyDistFilesTask
to copy the files out of dist
into the project root (which is why the files are listed in .gitignore here). But package.json references the copies under dist
directory, and the gulpfile's packageTask
references the copies under dist
(via outDir
). I can't tell that the copies in the project root are used at all, so I removed them.
If I've missed something, please let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gulp package
looks like it looks for files in the root directory:
chartjs-plugin-zoom/gulpfile.js
Line 64 in 8194ad6
gulp.src([outDir + '*.js', 'LICENSE.md']), |
Alternatively, you might be able to update gulp package
to look in dist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding Gulp correctly, it treats outDir
as the glob base for outDir + '*.js'
, so the files from dist
are included at the top level of the resulting zip file. Contrast with the explicit base
parameter for the samples
glob; those are included in a samples
subdirectory within the zip file:
chartjs-plugin-zoom/gulpfile.js
Line 68 in 8194ad6
gulp.src('./samples/**/*', {base: '.'}) |
I tested by running npm run build; npx gulp package
in a fresh copy of my branch, and it created a dist/chartjs-plugin-zoom.zip
file with contents similar to the releases on GitHub, so I think things are working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, we might need to update the comments in the packageTask
as they threw me off and look like they might be outdated:
// gather "regular" files landing in the package root
// since we moved the dist files one folder up (package root), we need to rewrite
// samples src="../dist/ to src="../ and then copy them in the /samples directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I found that confusing too. I just pushed some comments to try and clarify; feedback welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot clearer to me
Awesome. Thanks for this!! If you have any interest in contributing further, I'd love to get rid of |
Sure, I can take a look at removing gulp. Thank you. |
Oh, sorry! I did not see this 😞 |
No problem; I hadn't started yet. Thanks, @kurkle and @benmccann. |
Based off of chartjs-plugin-annotation's approach.
Specific changes:
Chart.Zoom
namespace. Since that namespace appears to be undocumented and unused, I removed it.The ESM version does not automatically register the plugin. This matches chartjs-plugin-annotation and seems to better match Chart.js 3's tree-shaking design.
I'm unclear on whether the UMD build should automatically register the plugin. Not registering seems to better match Chart.js 3, and chartjs-plugin-datalabels recently changed to no longer register, but chartjs-plugin-annotation's UMD build does register.