jsmediatags icon indicating copy to clipboard operation
jsmediatags copied to clipboard

Remove react-native-fs as dependency for non React Native projects

Open johngrimsey opened this issue 4 years ago • 9 comments

I've just installed jsmediatags into my Angular project.

npm install jsmediatags --save

After importing the module I get this:

./node_modules/jsmediatags/build2/ReactNativeFileReader.js
Module not found: Error: Can't resolve 'react-native-fs' in '/www/my-project/node_modules/jsmediatags/build2'

This is not available inside my project and I don't want to install it in order to use jsmediatags.

Can you remove the dependency for non React Native projects?

johngrimsey avatar Jul 09 '19 07:07 johngrimsey

+1

~~In the meantime, you can use version 3.8.1 of jsmediatags which didn't require react-native-fs to run.~~ Edit: look at my next post for a better solution

maxdup avatar Jul 09 '19 12:07 maxdup

Dude awesome thanks

johngrimsey avatar Jul 09 '19 17:07 johngrimsey

I’m actually not able to repro this :\ . What I did was: create a directory with a package.json with only the name, and an index.js with require(‘jsmediatags’). I then npm install jsmediatags --save and run node index.js which executed without an error.

The reason I’m surprised this happens is because the require(‘ReactNativeFileReader’) is inside an if that checks if it’s running under ReactNative, so it shouldn’t really be required in your case.

https://github.com/aadsm/jsmediatags/blob/dad42a42c9a6da8ee80f1bc125527ed5b40cbd8d/src/jsmediatags.js#L275-L276

aadsm avatar Jul 14 '19 06:07 aadsm

I'll admit my '+1' was kinda uneducated and unhelpful. I did some digging, here's the situation as I understand it.

First of all, I should have specified that this happens when bundling with webpack. React-native-fs is listed as "optionalPeerDependencies" in jsmediatags' package.json, which means it is not installed when doing "npm install jsmediatags", which is great, cause I don't really want it in my project. Webpack is pretty aggressive tho, and it doesn't matter that the dependencies are behind an if statement. Webpack will try to add react-native-fs to my bundle. The error message found in the first post is Webpack not finding the optional dependencies because they are not installed.

So, to be more precise, the actual issue is this: Webpack (with default configuration) will fail to package jsmediatags because of optional react dependencies. And even installing the optional dependencies manually seems not to work properly.

The best solution I found was to exclude react-native-fs from my bundle with some webpack externals configuration.

module.exports = { externals: { 'react-native-fs': 'reactNativeFs', } }

I'm not knowledgeable enough about npm packaging to know what your options are in addressing this issue as a package maintainer but adding this bit of configuration to the readme is the best suggestion I can offer at the moment.

maxdup avatar Jul 14 '19 16:07 maxdup

In theory, you shouldn't have to make any changes to your webpack configuration. There is a browser-specific build that doesn't include the React Native dependency. And there is this line in package.json that should tell webpack to use that build:

"browser": "dist/jsmediatags.js",

But the problem seems to be that this file is missing on npm for whatever reason. So I guess it's falling back to the "main" build, which does have the offending dependency.

brianchirls avatar Sep 03 '19 19:09 brianchirls

@johngrimsey I think this is the problem.

$ jq .version node_modules/jsmediatags/package.json 
"3.9.7"

$ jq .browser node_modules/jsmediatags/package.json
"dist/jsmediatags.js"

$ ls node_modules/jsmediatags/dist/jsmediatags.js
ls: node_modules/jsmediatags/dist/jsmediatags.js: No such file or directory

$ ls node_modules/jsmediatags/dist/
jsmediatags.min.js

The value of browser field is dist/jsmediatags.js, but the path doesn't exist as it's ignored by .npmignore. Once I changed browser field to dist/jsmediatags.min.js, it's bundled properly.

https://github.com/aadsm/jsmediatags/blob/2cc8ca5f49d788e360a3a9f18dc425e99ebf2af3/package.json#L22

https://github.com/aadsm/jsmediatags/blob/2cc8ca5f49d788e360a3a9f18dc425e99ebf2af3/.npmignore#L11

Leko avatar May 19 '21 08:05 Leko

Hi, I'm having errors with fs dependency. is it the same ?

Module not found: Can't resolve imported dependency "fs" Did you forget to install it? You can run: npm install --save fs

master-stm avatar Nov 06 '21 04:11 master-stm

its webpack behavior for non react app and you need to add any error returns to external object in webpack config. for me both 'react-native-fs' and 'fs' itself have been showing in error logs. add these then rebuild externals: { 'react-native-fs': 'reactNativeFs', 'fs': 'reactNativeFs'}

nemesisKO avatar Dec 06 '21 19:12 nemesisKO

Was this error solved? If yes, can someone explain in details what is to be done.

here are the error messages I am getting:

ERROR in ./node_modules/jsmediatags/build2/NodeFileReader.js 135:9-22
Module not found: Error: Can't resolve 'fs' in '...\node_modules\jsmediatags\build2'

ERROR in ./node_modules/jsmediatags/build2/ReactNativeFileReader.js 135:11-37
Module not found: Error: Can't resolve 'react-native-fs' in '...\node_modules\jsmediatags\build2'

ERROR in ./node_modules/jsmediatags/build2/ReactNativeFileReader.js 137:15-32
Module not found: Error: Can't resolve 'buffer' in '...\node_modules\jsmediatags\build2'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
        - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "buffer": false }

Iyin0 avatar Oct 23 '22 12:10 Iyin0