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

Package does not compile due to potential mismatch of "require" and "import" syntax #278

Open
mmartinezluis opened this issue Feb 14, 2024 · 17 comments

Comments

@mmartinezluis
Copy link

I'm using Nextjs V12. When trying to use the function-plot library via import statement, the library does not work. I get the below error:

isse_compiling

There seems to be an import mismatch between the d3-shape dependency and the chart.js dependency. I would appreciate help on solving this issue.

@mauriciopoppe
Copy link
Owner

Thanks for the report, which version of function-plot are you using?

@mmartinezluis
Copy link
Author

I'm using the latest version, 1.24.4

@mauriciopoppe
Copy link
Owner

I think it's happening because the dist files in dist/ emitted in v1.24.4 use CommonJS and the d3-* libraries use JS modules. So the flow is: JS Module (your app) -> CommonJS (function plot) -> JS Module (d3)

As a workaround try this import which uses a bundled version of function-plot which is the entire library in a single file:

import functionPlot from 'function-plot/dist/function-plot'

For the real solution the flow above needs to be JS Module (your app) -> JS Modlue (function plot) -> JS Module (d3). I switched to use JS modules in the master branch so you should be able to do import functionPlot from 'function-plot' in a future release.

@mmartinezluis
Copy link
Author

mmartinezluis commented Feb 14, 2024

Thank you for the response. I tried the work around, but it does not work:
error on importing library

error on importing library terminal

It seems that this is a breaking change.

@mmartinezluis
Copy link
Author

Since the documentaiton for Function-plot is solely written using JS Module syntax (and hence the users of Function-plot are more likely using ESM imports), I think that a new release for this seemingly breaking change should not be that difficult, given that you already updated the master branch for chart.js. I'll be looking forward to the release/fix. Thank you.

@mauriciopoppe
Copy link
Owner

I tried the following in a hello world parcel app and it did work:

import functionPlot from 'function-plot/dist/function-plot'

functionPlot({
  target: '#playground',
  data: [{ fn: 'x^2', graphType: 'polyline' }]
})

I suspect this might be a problem between the integration of the NextJS bundler and this library.


There's a dev build not ready for production usage that already uses JS modules, could you please try with this module? npm install [email protected]

@mauriciopoppe
Copy link
Owner

mauriciopoppe commented Feb 14, 2024

Related issue in a NextJS app #217 that I think was never solved.

@mauriciopoppe
Copy link
Owner

I've reproduced this issue with the following steps:

import functionPlot from "function-plot";
⨯ ./node_modules/function-plot/dist/chart.js:7:19
Module not found: ESM packages (d3-shape) need to be imported. Use 'import' to reference the package instead. https://nextjs.org/docs/messages/import-esm-externals

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/function-plot/dist/index.js
./src/app/page.js
  • Case 2: if src/app/page.js look like this:
import functionPlot from "function-plot/dist/function-plot";
⨯ node_modules/function-plot/dist/function-plot.js (1:205) @ self
 ⨯ ReferenceError: self is not defined
    at eval (webpack-internal:///(rsc)/./node_modules/function-plot/dist/function-plot.js:4:3)
    at (rsc)/./node_modules/function-plot/dist/function-plot.js (/private/var/folders/c1/clfklx952gg7v4tjck2t8j640000gn/T/tmp.TNCiGCJfdr/hello-world/.next/server/vendor-chunks/function-plot.js:20:1)
    at __webpack_require__ (/private/var/folders/c1/clfklx952gg7v4tjck2t8j640000gn/T/tmp.TNCiGCJfdr/hello-world/.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///(rsc)/./src/app/page.js:9:90)
    at (rsc)/./src/app/page.js (/private/var/folders/c1/clfklx952gg7v4tjck2t8j640000gn/T/tmp.TNCiGCJfdr/hello-world/.next/server/app/page.js:194:1)
    at Function.__webpack_require__ (/private/var/folders/c1/clfklx952gg7v4tjck2t8j640000gn/T/tmp.TNCiGCJfdr/hello-world/.next/server/webpack-runtime.js:33:42)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at process.processTimers (node:internal/timers:514:7)

@mmartinezluis
Copy link
Author

mmartinezluis commented Feb 14, 2024

With dev build version 1.25.0, the package loads:

loads

However, a new error shows on the application page:
default key not last one

The fix for the above error seems to be moving the "default" key from "exports" to the last place, as shown below:

move default key

@mauriciopoppe
Copy link
Owner

mauriciopoppe commented Feb 14, 2024

Thanks for the investigation, yes I saw a similar answer online, in addition I had to make a few changes to the dependencies included.

Anyways, first install the latest alpha version (not production ready yet) npm install [email protected].

The toy app I have looks like this:

"use client";

import React, { useRef, useEffect } from "react";
import functionPlot from "function-plot";
import styles from "./page.module.css";

export const FunctionPlot = React.memo(
  ({ options }) => {
    const rootEl = useRef(null);
    useEffect(() => {
      try {
        functionPlot(Object.assign({}, options, { target: rootEl.current }));
      } catch (e) {}
    });
    return <div ref={rootEl} />;
  },
  () => false,
);

export default function Home() {
  const options = {
    data: [{ fn: "x^2", graphType: "polyline" }],
  };
  return (
    <main className={styles.main}>
      <FunctionPlot options={options} />
    </main>
  );
}

@mauriciopoppe mauriciopoppe added this to the Road to 2.0.0 milestone Feb 14, 2024
@mmartinezluis
Copy link
Author

mmartinezluis commented Feb 18, 2024

Hi @mauriciopoppe ,

Thank you for the code. I just tested the code, and it shows an error:

import error

The error comes at the "import" line:

import functionPlot from 'function-plot';

@SnowyField1906
Copy link

it has been a month and will there any update for this in near future?

@mauriciopoppe
Copy link
Owner

mauriciopoppe commented Mar 20, 2024

I tried the changes in #278 (comment) and they work for me, here's my setup:

cd $(mktemp -d)
npx create-next-app@latest
cd my-app
npm install [email protected]
cat <<EOF > src/app/page.js
"use client";

import React, { useRef, useEffect } from "react";
import functionPlot from "function-plot";
import styles from "./page.module.css";

export const FunctionPlot = React.memo(
  ({ options }) => {
    const rootEl = useRef(null);
    useEffect(() => {
      try {
        functionPlot(Object.assign({}, options, { target: rootEl.current }));
      } catch (e) {}
    });
    return <div ref={rootEl} />;
  },
  () => false,
);

export default function Home() {
  const options = {
    data: [{ fn: "x^2", graphType: "polyline" }],
  };
  return (
    <main className={styles.main}>
      <FunctionPlot options={options} />
    </main>
  );
}
EOF
npm run dev

When I open the dev webpage I see no errors
image

@Linho1219
Copy link

Linho1219 commented Oct 24, 2024

Any follow-up on this issue? I encountered the same problem when using it (v1.25.0) in my Vitepress project. The dev server runs fine, but the build fails. I have tried the previous methods, and using import functionPlot from 'function-plot/dist/function-plot' results in the error:

ReferenceError: self is not defined
    at Module._compile (node:internal/modules/cjs/loader:1358:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Module._load (node:internal/modules/cjs/loader:1024:12)
    at cjsLoader (node:internal/modules/esm/translators:348:17)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:297:7)
    at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
    at async build (node_modules/vitepress/dist/node/serve-4DnZ8_Si.js:48721:24)
Node.js v20.15.1

When using the alpha version [email protected], a new error occurred:

(node:22056) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
.........\node_modules\web-worker\node.js:17
import URL from 'url';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1378:20)
    at Module._compile (node:internal/modules/cjs/loader:1428:41)
    at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
    at Module._load (node:internal/modules/cjs/loader:1104:12)
    at cjsLoader (node:internal/modules/esm/translators:346:17)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:286:7)
    at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
    at async build (file:///............../node_modules/vitepress/dist/node/serve-4DnZ8_Si.js:48721:24)

Node.js v20.17.0

@Linho1219
Copy link

Based on the error message, the problematic package seems to be web-worker. So, I found it in interval_worker_pool.ts and tried commenting out the import Worker from 'web-worker'. Surprisingly, this resolved the issue.

I looked into it and found that the web-worker package implemented atop Node's worker_threads, while in the browser, it's merely an alias for Worker. Since function-plot runs in the browser, I believe it's safe to remove this package to solve the problem.

@mauriciopoppe
Copy link
Owner

I checked that I'm using web-workers on the node side to do a few perf tests, however it was possible to use different implementations depending on where parts of the program are running. Through #320 web-worker is no longer a browser dependency.

Copy link

stale bot commented Feb 1, 2025

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Feb 1, 2025
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

4 participants