Tone.js icon indicating copy to clipboard operation
Tone.js copied to clipboard

cannot import in default Next.js app

Open DronHazra opened this issue 2 years ago • 7 comments

Describe the bug

I can't import Tone.js in a default Next.js app. I know that I can't use Tone.js in Node, but I'm dynamically importing Tone so that the component is not rendered on the server, only on the browser.

To Reproduce

Here's a repo that shows a minimum example. I created a Next app, imported Tone, and tried to run Tone.start() when the user clicks on a button.

Expected behavior

I expect to be able to import Tone. Tone should work in the browser (I'm not trying to use it in Node), but it's not and I'm not sure why.

What I've tried

I've tried using dynamic imports directly (as described here), putting the import in an Effect hook so it only ran on the browser. This also did not work. It keeps saying Tone.start() is not a function.

Additional context

I'm using Next.js 12.1.5, React 18, and Tone 14.8.38.

DronHazra avatar May 07 '22 14:05 DronHazra

I tried your minimum example and couldn't fix the issue fiddling with it. I do however have a next.js project running and working using the same approach as you tried using the following versions - "react": "^17.0.1", "react-dom": "^17.0.1", "tone": "^14.7.77" "next": "^10.0.9",

I tried to downgrade to these on your project, but I'm not entirely sure i downgrading everything correctly (and as i said i couldnt get rid of the error). Maybe try a new project with the above versions. let me know if you need / want any code from my project that might help...(its possible i came across this issue and fix it and have forgotten what i did, its been going a year or so).

cordial avatar May 12 '22 23:05 cordial

I have experienced the same problem. After trying many things, I found that there was a problem with the package manager. I think the tonejs have a incompatibility with 'Yarn pnp', so you need to change the yarn version to 'classic' instead of 'berry(yarn^2)' and reinstall the module.

# Change the yarn version
yarn set version classic

# Remove file related to yarn berry
# => .pnp.cjs, .pnp.loader.mjs, .yarn, etc.

# install modules
yarn install

Here is the package version that I use.

{
  ...
  "dependencies": {
    "next": "^12.1.6",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "tone": "^14.7.77"
  },
  ...
}

limitkr avatar Jun 27 '22 13:06 limitkr

Yeah, had the same problem. I have installed tone.js via npm install tone@next so I've got 14.8.40 version. Downgraded to 14.7.77 and problem has disappeared. @DronHazra your example is working if you downgrade tone.js version.

Vlsarro avatar Jul 09 '22 10:07 Vlsarro

Can anyone help me get Tone.js going with Remix? I'm getting this error:

`/my-remix-app/node_modules/tone/build/esm/core/Tone.js:7 import { version } from "../version"; ^^^^^^

SyntaxError: Cannot use import statement outside a module`

Tried putting type:module in the package.json but no go. Do you think reinstalling the package with @next would work for Remix?

wormholecowboy avatar Aug 03 '22 11:08 wormholecowboy

The problem here is that the 14.8 introduced the "type": "module" entry in the package.json and any NodeJS project trying to load tone now tries to load the ESM version. While the ESM generated code runs perfectly fine on browsers, in NodeJS, they need file extension paths.

One way to allow NodeJS to use the algorithm that resolves paths without extentions is by using this flag --es-module-specifier-resolution=node (see: the official NodeJS docs).

3dos avatar Aug 24 '23 13:08 3dos

The problem here is that the 14.8 introduced the "type": "module" entry in the package.json and any NodeJS project trying to load tone now tries to load the ESM version. While the ESM generated code runs perfectly fine on browsers, in NodeJS, they need file extension paths.

One way to allow NodeJS to use the algorithm that resolves paths without extentions is by using this flag --es-module-specifier-resolution=node (see: the official NodeJS docs).

That flag sadly didn't help, did anyone manage to get it working?

Paegasus avatar Sep 13 '23 19:09 Paegasus

The problem here is that the 14.8 introduced the "type": "module" entry in the package.json and any NodeJS project trying to load tone now tries to load the ESM version. While the ESM generated code runs perfectly fine on browsers, in NodeJS, they need file extension paths. One way to allow NodeJS to use the algorithm that resolves paths without extentions is by using this flag --es-module-specifier-resolution=node (see: the official NodeJS docs).

That flag sadly didn't help, did anyone manage to get it working?

Sadly, for now, we reverted back to 14.7 in order for Node to use the CJS version of ToneJS. Another option, which is clearly not ideal, would be to use fix-esm-import-paths on the installed lib with a post install npm hook.

3dos avatar Sep 25 '23 07:09 3dos