p5.js-sound
p5.js-sound copied to clipboard
p5 is not defined in /node_modules/p5/lib/addons/p5.sound.js:4323
Error Remake on Using npm in React App
import * as p5 from "p5"; import "p5/lib/addons/p5.sound";
Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, be sure to follow the issue template if you haven't already.
@suprim12 please mention the versions and some more detail.. It would be more helpful! Thanks
Same problem here, i use p5 in react (typescript).
In my case, when i import p5/lib/addons/p5.sound the error show up
import p5 from 'p5';
import 'p5/lib/addons/p5.sound';
let bloopOne: p5.SoundFile;
export function preBloop(p: p5): void {
const loadSound = (path: string) => ((p as any) as p5.SoundFile).loadSound(path);
bloopOne = loadSound('../audio/bloop1.mp3');
}
export function playBloop(): void {
bloopOne.play();
}
i use the latest version of p5
"p5": "^1.1.9", "react": "^16.13.1"
@ylahssini it would be great to see actuall error output ! thanks !
@endurance21 This is error output, i think it's related to webpack, and i use CRA:
Uncaught ReferenceError: p5 is not defined
at Object.<anonymous> (p5.sound.js:3112)
at Object.push../node_modules/p5/lib/addons/p5.sound.js (p5.sound.js:3160)
at __webpack_require__ (p5.sound.js:84)
at Object.<anonymous> (p5.sound.js:2885)
at Object.push../node_modules/p5/lib/addons/p5.sound.js (p5.sound.js:2956)
at __webpack_require__ (p5.sound.js:84)
at p5.sound.js:120
at Object../node_modules/p5/lib/addons/p5.sound.js (p5.sound.js:121)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Module../src/Rain/Bloops.ts (Bloops.ts:2)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Module../src/Rain/index.tsx (index.tsx:1)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Module../src/App.tsx (index.css:7)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Module../src/index.tsx (index.css?f3f6:45)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Object.1 (serviceWorker.ts:149)
at __webpack_require__ (bootstrap:784)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1
Has anyone been able to solve this? Have tried all discussed solutions in other threads with no luck.
@angerboy I solved like this:
import React, { useEffect } from "react"; import './globals'; import "p5/lib/addons/p5.sound"; import p5 from "p5";
and then in globals.js:
import p5 from "p5"; window.p5 = p5;
The problem is that p5 is available as global dependency when using webpack/create-react-app. I'm not sure if this is the best way to approach but it works, I got the idea from here: https://github.com/facebook/create-react-app/issues/4281
@LABCAT Thanks, I wonder if you could share your code? Having the same issue as well ): and can't figure this out.
@vennsoh I'm doing it in this repo: https://github.com/LABCAT/donuts-no-1/
see this file: https://github.com/LABCAT/donuts-no-1/blob/master/src/js/globals.js
and this file: https://github.com/LABCAT/donuts-no-1/blob/master/src/js/P5Sketch.js
@LABCAT
Your workaround seems to be working for only function calls?
I added window.p5 = p5 after calling import * as p5 from "p5"
import * as ml5 from "ml5"
window.p5 = p5
import "p5/lib/addons/p5.sound"
Then I'll be able to use the p5.loadSound() function. However if I try to use new p5.Envelope() constructor it'll still throw me an error.
export default function sketch(p5) {
p5.setup = () => {
p5.createCanvas(400, 400)
song = p5.loadSound(url("./assets/hurry.mp3")) // Will work
env = new p5.Envelope() // Will error
...
It'll say "ndex.js:296 Uncaught (in promise) TypeError: p5.Envelope is not a constructor" Do you know why?
According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_constructor It says p5.Envelope() is not a constructor...
@vennsoh @LABCAT
I have been working on this repo in this summer of code , I would like to help it out , but I am busy with my college schedule right now .
I would ask to use this current repo code of p5.sound instead what is present in "p5/lib/addons/p5.sound" ,
So how would you use current p5.sound file , it's simple just go to current repo , go to lib folder , and copy p5.sound.js from there and place it somewhere in your repo you might find appropriate to work with , and then import it using like you do and then TELL US THE RESULT .
It will help us figuring out if the same problem is with aall versions or what !!
@endurance21 Thanks. I've copied and replaced p5.sound files from https://github.com/processing/p5.js-sound/tree/master/lib
It's still the same problem so I doubt it's the version. The version that I'm using: /** [p5.sound] Version: 0.3.12 - 2020-01-06 */
Thanks a ton for this experiment @vennsoh . Let me tell you one more thing , we have some APIs that's uses audioworklet processors . I am.having doubt that if this is the problem with those audioworklet processors or what !
For this I would ask you to initiatize
P5.oscillator()
Instead of
p5.Envelope()
And see if same happens or what ! Also forgive me if I am counting too much on you for carrying out experiments and all. Hope you understand that..
All good. It's still the same problem @endurance21

Ah just changing p5.Envelope() --> p5.constructor.Envelope() fixes the problem!
@vennsoh good to hear that . But is the reason it's working .I am clueless right now .
Sorry I think I should be a little bit more specified. I used react-p5-js library to fix this problem. The comment thread is here.
https://github.com/and-who/react-p5-wrapper/issues/61
I was able to get everything working using the CDN script links in my index.html:
<script defer src=https://cdn.JsDelivr.net/npm/p5></script>
<script defer src=https://cdn.JsDelivr.net/npm/p5/lib/addons/p5.dom.min.js></script>
<script defer src=https://cdn.JsDelivr.net/npm/p5/lib/addons/p5.sound.min.js></script>
I then waited for window.p5 to be defined:
useEffect(() => {
// Wait until p5 is loaded
p5Interval = window.setInterval(() => {
if(window.p5) {
p5 = window.p5;
myp5 = new p5(Sketch, myRef.current);
window.clearInterval(p5Interval);
}
}, 100);
}, []);
No idea how we could propose this change, but, it seems like p5.sound.js is missing the p5 dependency, so, my fix was to do the following,
In node_modules/p5/lib/addons/p5.sound.js
FIND
/** [p5.sound] Version: 0.3.12 - 2020-01-06 */
REPLACE WITH
import p5 from "p5" // import the missing dependency, obviously not a permanent fix, but, simple
/** [p5.sound] Version: 0.3.12 - 2020-01-06 */
I'm sure there's a solid motivation for structuring the code this way, but, it's doesn't seem very npm friendly. Does @anyone know why it is assumed that p5 is global and/or why node_modules/p5/lib/addons/p5.sound.js is already packed with webpack?
@vennsoh I'm doing it in this repo: https://github.com/LABCAT/donuts-no-1/
see this file: https://github.com/LABCAT/donuts-no-1/blob/master/src/js/globals.js
and this file: https://github.com/LABCAT/donuts-no-1/blob/master/src/js/P5Sketch.js
Oh my god, this ^ - absolute life saver, I've been trawling every thread over this issue and this fixed it perfectly. The primary difference for me was including import * as p5 from "p5"; and window.p5 = p5; in a seperate file before importing into the sketch.
Thank you! 🤘
This looks like a duplicate of https://github.com/processing/p5.js-sound/issues/453 and https://github.com/processing/p5.js/issues/4479
I can confirm it is not a problem with Webpack alone - the problem exists in all modern module loaders/compilers including RollUp, TypeScript and Parcel.
Having tested more thoroughly, I can confirm P5 add-ons won't load in the following configurations:
- CommonJS
- ES6 > ES5 using Babel or esm
- ES Modules
Given the enournous populariity of npm and yarn, this issue means that anyone using those package managers will not be able to use p5 with add-ons.
What was it that changed between v0.9 and v1 that broke it?
@rjbultitude The basic thing this library is assuming that , p5 is a global variable. so users first need to make available p5 as global or in the scope of p5.sound apis .
does it sounds good ?
Thanks for the quick reply @endurance21 I think there are a few fundamental problems:
- There are no instructions in the Get Started page that explain how to install and configure p5 and add-ons via NPM or Yarn
- Most developers expect frameworks and libraries to manage their own namespacing
- This wasn't a problem in earlier versions, so it seems a breaking change was introduced at v1.0 that needs to be clearly communicated.
Are you saying the current solution is to import p5 then assign it to the window object? e.g. window.p5 = p5;
@rjbultitude i havenot tried btw , but my intuitions says it well !
How shall we proceed then? As per point 2 above, p5 should handle its own namespacing, which would fix this issue and 4479.
Also, do you know the answer to point 3? Why were p5 add-ons able to access the p5 object in v9.0?
I'll make a new issue for the missing instructions, if there's not one already.
I've tested the assignment of p5 to the global namespace and can confirm it does not work using ES2015 syntax e.g. import p5 from 'p5'; window.p5 = p5; import 'p5/lib/addons/p5.sound';
As far as I can tell, any compiler will fail to load the add-ons hence the other issues about TypeScript, p5-dom and so on
it only works if you use CommonJS (Node) syntax: const p5 = require('p5'); window.p5 = p5; require('p5/lib/addons/p5.sound');
Does anyone know what changed between v0.9 and v1.0? @therewasaguy @lmccart
Is there a discussion or plan to modernise p5 so that it works with the primary three module patterns and all common loaders/compilers?
Happy to help but am missing context.
Another relatively clean workaround until this gets properly fixed (so that others don't waste hours):
- Include the libraries directly in your index.html as script tags:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/addons/p5.sound.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ml5.min.js"></script>
- Declare the globals and use p5 in instance mode:
declare const p5: any;
declare const ml5: any;
...
new p5((sketch: any) => {
let mic: any;
sketch.setup = () => {
mic = new p5.AudioIn();
mic.start(() => {
const audioContext = new AudioContext();
pitch = ml5.pitchDetection(MODEL, audioContext, mic.stream, ...);
});
};
...
}
If you run into this problem and so happen to be using webpack - there is the imports-loader that can be used
https://webpack.js.org/loaders/imports-loader/
I have a config like this:
module: {
rules: [
{
test: path.resolve(__dirname, 'js/libs/easycam/p5.easycam.js'),
use: "imports-loader?p5=>require('p5')"
},
{
test: path.resolve(__dirname, 'node_modules/p5/lib/addons/p5.sound.js'),
use: "imports-loader?p5=>require('p5')"
},
{
test: path.resolve(__dirname, 'node_modules/p5/lib/addons/p5.sound.min.js'),
use: "imports-loader?p5=>require('p5')"
},
It'd be nice to have p5 sound work without relying on p5 as a global :-|
For anyone looking at this solution, the docs for imports-loader have been updated:
module: {
rules: [
{
test: path.resolve(
__dirname,
"node_modules/p5/lib/addons/p5.sound.js"
),
loader: "imports-loader",
options: {
type: "module",
imports: "p5",
},
},
{
test: path.resolve(
__dirname,
"node_modules/p5/lib/addons/p5.sound.min.js"
),
loader: "imports-loader",
options: {
type: "module",
imports: "p5",
},
},
]
}
Using require fix the compatibility
import p5 from "p5"
window.p5 = p5
require('p5/lib/addons/p5.sound')