music-metadata-browser
music-metadata-browser copied to clipboard
Can't use this package with vite 3
Hey, I currently use music-metadata with a buffer polyfill and vite 2 in my project. I would like to switch to this package (which is intended for the use in the browser) and vite 3. Sadly, it does not work, and I get the following error. I tried to polyfill the events module, but that led to more similar errors and I got into polyfilling hell.
Uncaught Error: Module "events" has been externalized for browser compatibility. Cannot access "events.EventEmitter" in client code.
at Object.get (browser-external:events:9:13)
at node_modules/readable-web-to-node-stream/node_modules/readable-stream/lib/_stream_readable.js (_stream_readable.js:32:10)
at __require (music-metadata-browser.js?v=8f4e2ce6:3:50)
at node_modules/readable-web-to-node-stream/node_modules/readable-stream/readable-browser.js (readable-browser.js:1:28)
at __require (music-metadata-browser.js?v=8f4e2ce6:3:50)
at node_modules/readable-web-to-node-stream/lib/index.js (index.js:4:27)
at __require (music-metadata-browser.js?v=8f4e2ce6:3:50)
at node_modules/music-metadata-browser/lib/index.js (index.js:6:39)
at __require (music-metadata-browser.js?v=8f4e2ce6:3:50)
at dep:music-metadata-browser:1:16
I created a minimal reproduction of the issue here: https://github.com/lennyanders/music-metadata-browser-8-with-vite-3.
There you just need to execute npm i
, after that npm start
and then you can see the error in the browser console.
Thanks for looking into it and if I can be of any help, please let me know.
I bumped into the same issue, also getting ReferenceError: global is not defined
and ReferenceError: process is not defined
(both which can be overrided in vite config define
).
I think you need to polyfill:
music-metadata-browser is CommonJS module. Eventually I would like to provide an ES-Module music-metadata also works in client side environment. Closes effort that can be found in the es-module-with-browser-support branch. I welcome help with that.
I got it working using a buffer, events and utils polyfill and a bit of vite config trickery.
Here is the branch with the working code: https://github.com/lennyanders/music-metadata-browser-8-with-vite-3/tree/music-metadata-with-polyfills
I might look into you'r branch though (and maybe music-metadata itself), since I'm not so happy using it like this.
One of the things you may run into using the ESM is the way Node.js modules are imported. They use the node:
URL prefix. I am not sure if that helps, or makes it very difficult to polyfill Node.js modules.
I already handled that with an alias in vite, from node:buffer to buffer. https://github.com/lennyanders/music-metadata-browser-8-with-vite-3/blob/28bc592464a50e6c0be8672a9169c393393fecc0/vite.config.js#L10
Hi @lennyanders, I had a look to your music-metadata-with-polyfills. So that is the ESM way music-metadata. That's great, first time I think I actually see it working in the browser!
What you do not have in music-metadata version 8.0.1 are the specialized browser functions, like parseBlob
which music-metadata-browser adds. I want to move those into music-metadata.
The idea es-module-with-browser-support branch was to add that part.
Are you willing to further develop the browser compatibility of the music-metadata ESM version?
I also struggled a little bit to use this package with vite, react & typescript, but here is how i managed to make it run:
npm install buffer @esbuild-plugins/node-globals-polyfill @esbuild-plugins/node-modules-polyfill
then in vite.config.js
:
export default defineConfig({
// your other settings...
optimizeDeps: {
esbuildOptions: {
define: {
global: 'globalThis',
},
plugins: [
NodeGlobalsPolyfillPlugin({
buffer: true,
}),
],
},
},
});
Then it works flawless. My packages versions:
"vite": "^3.2.3",
"music-metadata-browser": "^2.5.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
update: just one plugin: https://github.com/grikomsn/vite-plugin-ngmi-polyfill
I solved it with vite4 and vue3. Here is my config
export default defineConfig({
...sharedConfig,
build: {
rollupOptions: {
// for production
plugins: [rollupNodePolyfillsPlugin()],
},
},
resolve: {
alias: {
// by node-globals-polyfill
events: 'rollup-plugin-node-polyfills/polyfills/events',
},
},
optimizeDeps: {
esbuildOptions: {
plugins: [
NodeGlobalsPolyfillPlugin({ buffer: true, process: true }),
NodeModulesPolyfillPlugin(),
],
},
},
})
My packages versions:
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"music-metadata-browser": "^2.5.9",
"rollup-plugin-polyfill-node": "^0.12.0",
"vite": "^4.1.4",
"vue": "^3.2.45",
Thanks for sharing your solution @subframe7536
I think you need to polyfill:
music-metadata-browser is CommonJS module. Eventually I would like to provide an ES-Module music-metadata also works in client side environment. Closes effort that can be found in the es-module-with-browser-support branch. I welcome help with that.
This now implemented: you may try music-metadata ≥ 9 , which is guaranteed Buffer free.