Skip to content
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

CDN version of the plain (esm) chart.js cannot be imported? #11592

Open
Pomax opened this issue Nov 23, 2023 · 23 comments
Open

CDN version of the plain (esm) chart.js cannot be imported? #11592

Pomax opened this issue Nov 23, 2023 · 23 comments

Comments

@Pomax
Copy link

Pomax commented Nov 23, 2023

Expected behavior

I expected to be able to import Chart from the CDN url https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.js

Current behavior

Uncaught (in promise) TypeError: The specifier “@kurkle/color” was a bare specifier, but was not remapped to anything. Relative module specifiers must start with “./”, “../” or “/”.

Reproducible sample

no full example necessary

Optional extra steps/info to reproduce

Open a dev console and run import("https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.js").then(lib => console.log(lib)). It'll error out.

Possible solution

No response

Context

https://www.chartjs.org/docs/latest/getting-started/installation.html suggests that if you don't want to use npm (for instance, you're working on a "classic" web page that's just static HTML, CSS, and JS) you can use one of several CDNs with CDNJS listed as first option, so that's what folks will most likely go for.

https://www.chartjs.org/docs/latest/getting-started/integration.html then teaches people that it's an ES module so import works out of the box, and so we run into a problem because instead it errors out.

chart.js version

4.4.0

Browser name and version

n/a

Link to your project

n/a

@mukham12
Copy link
Contributor

mukham12 commented Nov 26, 2023

May be similar to #10915.

@hfingler
Copy link

hfingler commented Nov 26, 2023

Just found the same issue and, following the issue mentioned above, solved it by linking the version with "umd" in its name. For example, <cdn>/Chart.js/4.4.0/chart.umd.min.js

@Pomax
Copy link
Author

Pomax commented Nov 26, 2023

@mukham12 that's a server-side issue though, so probably caused by something else.

@hfingler that's not really a solution if you're writing modern JS with ES modules, though. UMD exports are incompatible with ESM, You just end up importing a module that has no exports, which means you still can't do anything.

(open dev tools, and run import("https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.umd.js").then(module => console.log(module)); for example. You'll see it succeed because the JS file exists, but you'll also see it show an empty module)

@hfingler
Copy link

Good point. I'm working on a small, simple project, so that was enough for me.

@Pomax
Copy link
Author

Pomax commented Nov 27, 2023

Same, but I'm only working in modern JS these days (both in the browser and in Node), so it has to be ESM-loadable.

@ludgerh
Copy link

ludgerh commented Dec 10, 2023

This does not work nether, even with a very simple example page, basically slightly varied from the first step in the tutorial. I am using Django and had no problem with the version 3. I would prefer not to get back to this version for the new project. Now I get (the server from the browsers error message is my static files server, I have no idea, why/how Firefox looks there):

Source-Map-Fehler: Error: request failed with status 404
Ressourcen-Adresse: https://myserver.de/sh2/js/chart.umd.js
Source-Map-Adresse: chart.umd.js.map
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
</head>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.umd.min.js"></script>

<div>
  <canvas id="myChart"></canvas>
</div>

<script>
  console.log(Date.now());
  const ctx = document.getElementById('myChart');
  new Chart(ctx, {
    type: 'line',
    data: {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  });
</script>

@ludgerh
Copy link

ludgerh commented Dec 10, 2023

...found an easy solution that works for me:

@Pomax Pomax changed the title CDN version of chart.js cannot be imported? CDN version of the plain (esm) chart.js cannot be imported? Dec 10, 2023
@Pomax
Copy link
Author

Pomax commented Dec 10, 2023

@ludgerh that's a different version with a different problem, though. I've updated the title, but for this particular it'll be better to delete those comments and file a separate one.

@devlaam
Copy link

devlaam commented Feb 17, 2024

Imagine you are selecting a JS lib do charting for your project and try to run some simple tests in the browser. This bug is a complete dealbreaker. "Moving on to then next lib ... ". Surly hope this is fixed soon.

@benjaoming
Copy link

I ran into the same issue, which seems to be that the documentation and the CDN deployed scripts suffer from some mismatch.

My main "use case" here is that I was trying to avoid having a package.json file and an NPM stack in a tiny prototype.

@Zafkiel45
Copy link

I'm with the same problem in Vanilla JavaScritp... The unique solution was to use the CDN from the example in the documentation. Without Typescript or imports, only the link of CDN in the script tag.

@ferouzkassim
Copy link

@Zafkiel45 i was running through the same issue al i did was download the source files then have ascript tag in my html before i imported my other js script so teh variable Chart will alwasy be got from the script above it i hope others wi be alble to fix it the sae way

@benc-uk
Copy link

benc-uk commented Nov 10, 2024

Chart.js feels more than a little out of step with modern JS if I can't import it from a ESM source, the entire ecosystem of JS is moving on from UMD

Having to using script tags in the HTML is a massive step backwards

@Pomax
Copy link
Author

Pomax commented Nov 11, 2024

Using script tags is perfectly fine (and actually improves performance because you're letting the browser take care of caching. The biggest crime against getting the best performance is bundling) but the lack of a working library is a bit of a problem.

@ferouzkassim
Copy link

ferouzkassim commented Nov 11, 2024 via email

@lonix1
Copy link

lonix1 commented Nov 11, 2024

using script tags in the HTML is a massive step backwards

Keep in mind not everyone uses Node-related tools. So some of us just need a working script we can load from a CDN.

@benc-uk
Copy link

benc-uk commented Nov 11, 2024

using script tags in the HTML is a massive step backwards

Keep in mind not everyone uses Node-related tools. So some of us just need a working script we can load from a CDN.

I'm not using Node, I'm trying to use Chart.js in a vanilla JS project using ESM and modules, i.e. import { Chart } from 'some-cdn-url-here' in a JS file, no Node, no bundling & no TypeScript

The ESM CSN version available at this URL https://cdn.jsdelivr.net/npm/chart.js@4.4.6/+esm doesn't work, as it hasn't been correctly bundled and has external imports that don't work

@ferouzkassim
Copy link

<script src="~/lib/chrt443/chart.umd.js"></script>

load this in your index html that is after downaoding the files from the repo then after it will load the chartjs ina the dom then after do soething like this
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [
{
label: 'Total Quantity Left',
type: 'line',
data: alignedProductQuantities,
backgroundColor: 'rgba(49, 197, 243)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
},
{
label: 'Sold this Month',
type: 'line',
data: alignedOrderCounts,
backgroundColor: 'rgba(78, 132, 135)',
borderColor: 'rgba(142, 142, 142)',
borderWidth: 2,
fill: false,
tension: 0.4
}
]
}, then it wil consider thee variable Chart as one that comes from te window objecct so it will be globally accesed in your application you dont have to import it as an esm module

@Pomax
Copy link
Author

Pomax commented Nov 12, 2024

@ferouzkassim please read the first comment, which clearly explains that your comment shouldn't be in this thread because it's specifically about loading Chart.js, the plain ESM version, from CDN. The code you're showing is neither of those things, and it would be much more helpful if you deleted it again.

@altbdoor
Copy link

altbdoor commented Nov 14, 2024

I was able to make ChartJS work in ESM, by loading it from https://esm.sh instead. I've also made a minimal example in https://stackblitz.com/edit/vitejs-vite-1jfgup?file=index.html

The general idea is to:

  1. Start by importing https://esm.sh/chart.js@4.4.6?bundle-deps=
    • ?bundle-deps will bundle the two dependencies that causes trouble in jsdelivr
  2. This URL can be used in .mjs with either:
    1. dynamic imports, const chartlib = await import(''), or
    2. import statements, import * as chartlib from ''
    3. chartlib is a placeholder name, feel free to call it whatever you want
  3. If tree-shaking is needed, we can go further with ?exports= (see esm.sh docs)

Edit: for the sake of brevity...

  1. Using esm.sh requires you to manually register the components/plugins

    import * as chartlib from 'https://esm.sh/chart.js@4.4.6?bundle-deps=';
    
    // to register everything
    chartlib.Chart.register(...chartlib.registerables);
    
    // to register some, but really only makes sense with `?exports=`
    // for what can be exported, see https://www.chartjs.org/docs/latest/getting-started/integration.html#bundle-optimization
    chartlib.Chart.register(chartlib.Chart, chartlib.BarController, chartlib.BarElement);
    
    const chart = new chartlib.Chart();

@Pomax
Copy link
Author

Pomax commented Nov 14, 2024

That is an excellent workaround for now, thank you for posting that.

@benc-uk
Copy link

benc-uk commented Nov 15, 2024

I'll second that! I just tried this workaround, using esm.sh and it's working great in my mjs code, and thanks for the working example as I would have never found the need to call Chart.register() myself

Awesome thank you

@altbdoor
Copy link

@benc-uk that action wasn't really clear to me either, as it was implicitly handled in auto.js, which would be 99% of any dev's entry point 💡

Chart.js/auto/auto.js

Lines 1 to 3 in bb82c8f

import {Chart, registerables} from '../dist/chart.js';
Chart.register(...registerables);

When I explored proper tree-shaking with esm.sh, that's when I found #10163 , which shows how registration works 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests