Skip to content

Update chart.js dependency #126

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

Closed
wants to merge 1 commit into from
Closed

Update chart.js dependency #126

wants to merge 1 commit into from

Conversation

gbere
Copy link
Contributor

@gbere gbere commented Jul 8, 2021

Q A
Bug fix? no
New feature? yes/no
Tickets Fix #86
License MIT

@@ -63,7 +65,7 @@ var _default = /*#__PURE__*/function (_Controller) {
options: payload.options
});

var chart = new _chart.Chart(this.element.getContext('2d'), payload);
var chart = new _auto["default"](this.element.getContext('2d'), payload);
Copy link
Contributor Author

@gbere gbere Jul 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From tests:

var chart = new _auto["default"](this.element.getContext('2d'), payload);

ReferenceError: ResizeObserver is not defined.

But from one application works well

@weaverryan
Copy link
Member

Yo @gbere!

Thanks for this! I think this is an important one to get done. It's also the first time that we've hit this situation (though, I think it'll be fairly common): where we are bumping the dependency of a JavaScript library a full version.

In a perfect world, we would have 2 controllers (for awhile at least) - a Chartjs v2 version and a Chartjs v3 version - and automatically (at build time) "toggle" between them based on which version of chartjs is installed. This is easy in theory (it's just an if statement), but Webpack doesn't like conditional imports like this :). You CAN do something like this (taken from React):

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}

But I don't believe you can add a more complex conditional that checks what version of Chart.js is installed (at least, we can't do this without requiring the user to add some extra fanciness to their webpack config, which we can't do).

So, another solution would be to make 2 controllers (for v2 chartjs and v3) and then make the user toggle between them. That would be done by adding a 2nd controller here -

"chart": {
"main": "dist/controller.js",
"webpackMode": "eager",
"fetch": "eager",
"enabled": true
}
- probably called chartv3. Then, to avoid the user having BOTH activated when you install the package, you would set the original controller to enabled: false.

The downside of this would be that, if you use chartv3, then that is literally the new name of the controller (so the documentation would have to be tweaked to show that you need to use one or the other based on your situation).

A third solution, which isn't possible right now, would be to allow users to have an extra key in their controller.json file that would point to which specific file (e.g. dist/controller-v3.js) in the package that should be imported. Then we could keep the old one (but deprecate it), and make sure that this new key (e.g. file: 'dist/controller-v3.js') is included in new installs.

OR, hopefully I'm missing some cool idea :)

@gbere
Copy link
Contributor Author

gbere commented Jul 13, 2021

I think the best way to switch between major versions of chartjs dependency is increase the major version of symfony / ux-chartjs. But seeing that all ux- bundles share version, I understand that they have another usage.

Any suggestions how to pass the tests?

@gbere gbere changed the title Update chart.js. Resolves #86 Update chart.js dependency Jul 15, 2021
@weaverryan
Copy link
Member

@gbere Yea, this is really tricky.

After thinking about this more, I think we should attempt to combine solutions 1 & 3.

This would require work in https://github.com/symfony/stimulus-bridge. The general idea is this:

A) That library contains a webpack "loader" that's responsible for parsing the controllers.json file and then generating a "JavaScript source string" that contains import statements for all the files. Most of that work is done in this file: https://github.com/symfony/stimulus-bridge/blob/ed4434c4a80a603ada2fb648c8d2aa8924df7565/src/webpack/create-controllers-module.js#L14 - this line specifically reads the "main" key from the package's package.json file to complete the filename that should be imported - https://github.com/symfony/stimulus-bridge/blob/ed4434c4a80a603ada2fb648c8d2aa8924df7565/src/webpack/create-controllers-module.js#L59

B) I think we need add a "hook" in this process where an end-user library could have a module that exports a function that the above code calls. The purpose of this function would be to dynamically resolve this file should ultimately be imported.

For example, let's think about chart.js. It currently has a package.json file that specifies exactly which one file to load when the user's controllers.json file points to it: https://github.com/symfony/ux/blob/main/src/Chartjs/Resources/assets/package.json#L9

Instead of having a main key, we could optionally allow packages to have a resolveMain key, which points to a file in the package (e.g. dist/resolve_main.js). This would export a function that would return the file to import - e.g.:

export default () => {
    return 'dist/controller.js';
}

Of course, if your use-case is this simple, then you would continue to specify the main key and not create this function. BUT, you could then include conditional code in this callback:

export default () => {
    let chartVersion = null;
    try {
        chartMajorVersion = Math.floor(require(`chart.js/package.json`).version);
    } catch (e) {
        throw new Error('Please make sure that chartjs is installed. Run yarn ...');
    }

    switch (chartMajorVersion) {
        case 2:
            return 'dist/controller.js';
        case 3:
            return 'dist/controller-v3.js';
        default:
            throw new Error(`chart.js version ${chartMajorVersion} is not supported`);
    }
}

This would allow the library - ux-chatjs - to intelligently toggle which of the 2 controllers to import without extra config needed from the user (since it detects which version is available).

@Huluti
Copy link
Contributor

Huluti commented Nov 30, 2021

Hi! For information chart.js is now at version 3.6.1. Can't wait to enjoy it! Thank you for your work :)

@weaverryan
Copy link
Member

I've rebased (after all of our build changes) over on #185

@weaverryan weaverryan closed this Dec 2, 2021
tgalopin added a commit that referenced this pull request Dec 6, 2021
This PR was merged into the 2.x branch.

Discussion
----------

Adding support for Chartjs 3

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| Tickets       | Fixes #86
| License       | MIT

This takes the work from #126 and rebases so we can finish on the 2.x branch.

Commits
-------

444b7ea Fixing chartjs test and rollup process
38bd8c2 Update chart.js. Resolves #86
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Chart.js] v3 support
3 participants