Problem using p5 'esm' via jsdeliver (cdn)

Hello,

I am very new to javascript and even more to ES modules. However, I think I am trying things out correctly here. But as I am not sure if I am doing things right, I first drop a question here before I report an issue at either jsdeliver or p5. My final question will be: is this a bug, or am I doing things wrong?

I am trying to use the p5 via cdn as esm from jsdeliver. However, when trying to load my html, the console reports

jsdelivr-header.js:7 Uncaught SyntaxError: The requested module '/npm/@davepagurek/bezier-path@0.0.2/+esm' does not provide an export named 'createFromCommands' (at jsdelivr-header.js:7:1)

as far as I could find in here in the bezier-path source, the createFromCommands command does get exported (but again I am totally new to modules, so I am not sure if my conclusion is right).

As I am not sure how to use esm modules, I asked ‘Gemini AI’ for a usage example. Trying to use that example results in the same error.
Here is my html

<!DOCTYPE html>
<html>
<head>
  <title>p5.js ESM from jsDelivr Example</title>
  <style>
    body { margin: 0; }
    canvas { display: block; }
  </style>
</head>
<body>
  <script type="module">
    import p5 from 'https://cdn.jsdelivr.net/npm/p5@2.0.1/+esm';

    let x = 100;
    let y = 100;
    let speedX = 2.5;
    let speedY = 3;

    function setup() {
      createCanvas(400, 300);
      noStroke();
      fill(255, 0, 150);
    }

    function draw() {
      background(220);
      ellipse(x, y, 50, 50);
      x += speedX;
      y += speedY;

      if (x > width - 25 || x < 25) {
        speedX *= -1;
      }
      if (y > height - 25 || y < 25) {
        speedY *= -1;
      }
    }

    // You can also use the instance-based approach if you prefer
    // const mySketch = function(p) {
    //   let circleX = 50;
    //   let circleY = 50;
    //
    //   p.setup = function() {
    //     p.createCanvas(200, 150);
    //     p.fill(0, 100, 200);
    //     p.noStroke();
    //   };
    //
    //   p.draw = function() {
    //     p.background(240);
    //     p.circle(circleX, circleY, 30);
    //     circleX += 1;
    //     if (circleX > p.width + 15) {
    //       circleX = -15;
    //     }
    //   };
    // };
    //
    // new p5(mySketch);

  </script>
</body>
</html>

So now again my question, is the above described behavior due to a bug or me doing things the wrong way?

Thank you!

A JS script using type “module” doesn’t behave the same way as a regular 1.

1 of its many “gotchas” is related to declaring variables using keywords var & function.

For example, your 2 functions function setup() {} & function draw() {} will have different global visibility depending on whether they’re being run using type “module” or not!

For regular JS script type, the variable declaring keyword function (and var as well) will also append the variables setup & draw on the globalThis:

However, for type “module”, that won’t happen!

B/c neither setup() nor draw() callbacks are present on globalThis, p5js won’t “see” them; and thus your sketch won’t run!

As a workaround, you can manually add those 2 function variables as globalThis properties:

globalThis.setup = setup;
globalThis.draw = draw;

That is very useful information, I would be one step closer to getting the ‘module’ setup to work. Just, I still need to get rid of that error message when trying to use the ‘esm’ library.
I guess, there is something wrong with that ‘esm’ package on jsdeliver, but I am not sure (how it should work). Anyway, after getting it ‘imported’ I will be aware of your ‘advice’. Thank you very much for this explanation :slight_smile:

Officially there’s no ESM version of p5js.
p5js has always been a regular non-ESM frontend library.

And by the looks of that bezier-path:

Those imports are incompatible w/ browser ESM syntax b/c they’re using filenames w/o their extension!

For example, import { BezierSegment } from "./BezierSegment";
should be instead: import { BezierSegment } from "./BezierSegment.ts";

Browsers only accept the full filename, including its extension, for the keyword import.