This module does not seem to work with React Native Platform extensions import foo from 'components/foo'
where foo is one of foo.android.js or foo.ios.js
Works fine if i drop the android/ios part of the extension or if I fully specify ./components/foo
babelrc:
{
'presets': ['react-native'],
'plugins': ['transform-decorators-legacy',
["module-resolver", {
"root": ["./app"],
"alias": {
"test": "./test",
"underscore": "lodash"
},
"extensions": [".android.js", ".ios.js"]
}]
]
}
I wonder if this is a general bug in the plugin or something specific in react-native. I heard in the past that plugins which overrides the paths don't really work in react-native.
With that being said, I'll test your configuration and see if this is something that require a fix here.
@tleunen Any updates on this? I have the same problem.
Sorry, I'm checking it this weekend. I've been really busy for these past 2 weeks that I have quite a few things to catch up with my OSS projects.
I appreciate for the time you spent on this. It's been really helpful for me. I was thinking if I can fork and create a specific version for React Native where I can resolve modules depending on the result of RN's Platform.OS.
Forget about it, it did not work.
It might be something with react native. I remember a ticket saying it was hard to make it work with react native. Here it is #29
I've tested the custom extensions and everything is working fine. requiring foobar is redirecting to ./foobar.android.
I'd need more information to reproduce the issue, but it looks like the plugin doesn't run in your RN setup.
Closing it because using a custom extension works fine. Let me know if there's anything I can do to help, but my knowledge of RN is very limited.
@tleunen I tried to switch from module-alias to module-resolver today and this seems to be a bug.
{
"presets": [
"react-native-stage-0/decorator-support"
],
"plugins": [
[ "./src/relay/babelRelayPlugin" ],
["module-resolver", {
"root": ["./src"],
"extensions": [".android.js", ".ios.js", ".js"]
}]
]
}
requring file with extension inside a file with extension is actually broken.
eg:
Require chains:
app.js
-> require component
-> require foo
App directory:
- app.js
- component.ios.js
- component.android.js
Foo directory structure:
foo
index.ios.js
index.android.js
Would it be possible fo your to setup a very small project to reproduce the issue?
I'd love to help and find a solution but I've never setup a RN project so I don't really know where to start
sure. let me create a small repro for you.
@tleunen here: https://github.com/chirag04/moduleResolver. It should be self explanatory. let me know if i can help you debug this.
Appreciate your help 馃憤
Gracias! I'll take a look when I get a moment this week.
@chirag04 Could you explain a bit how I'm supposed to test? I see the import 'component' and I believe that's what should trigger the error, right?
But when I run npm start, I don't see any error in the console. And at the same time I don't know how to launch the emulator if the error only occurs inside the emulator? My xcode doesn't seem to want to open the project :/
ideally import 'component' should not trigger the error. It is erroring out currently and thats the bug i think.
To test: you can simply run react-native run-ios from the root directory.
I got an error, then I run it with npm start -- --reset-cache and got it working...

But I see the android version of the components. I'm guessing it's because it picks the first file, wich is android? How does this work usually with RN? Should it pick the right file based on the platform?
I set a log in the module-resolver plugin and it seems the resolver works fine, except maybe it always pick android:
component becomes ./component/index.android
foo becomes ../foo/index.android
yeah. so that's the bug. RN packager picks the right index.{platform}.js file. In this exaple we want componnet/index.ios to be picked up
Gotcha, I'll see if it's possible to grab an environment variable from RN to know which platform is built, and maybe add a new option in the plugin to set it in a "RN" mode.
I don't know the internals but maybe you can let the rn packager handle this part?
Hmm.. Thanks, it made me rethink a bit how the custom extensions work. I think it's a little bit buggy right now.
But at the same time, if the user sets a custom extension, the extension should be printed in the resulted path, in order for NodeJS or any other tooling system to pick it without issue.
I'm still not sure how to handle properly the case for RN.
@tleunen wondering if you were able to resolve this?
No, not really... :/ Not sure how to properly fix the issue.
If you have an idea, let me know...
My issue is similar, but in my case, babel resolver is not working at all.
I have the same babel config as above comments
{
"presets": ["react-native", "stage-0", "es2015"],
"plugins": [
"transform-decorators-legacy",
[
"module-resolver",
{
"root": ["./app"],
"extensions": [".android.js", ".ios.js", ".js"]
}
]
]
}
problem:
import mainStore from './redux/mainStore' will work
import mainStore from 'redux/mainStore' will not work
That looks like it's not working, or maybe I'm missing something in the config
Just find out. Since react-native version 0.41.2 , there no need for babel stage-0 and es2015. reactive-native already built in some of those features.
So if you want babel-plugin-resolver to work. should not include those presets in your babel config. This is what it should look like. This example doesn't mean to be a solution for the original issue. But rather an example of how to config babel-plugin-resolver with react-native
{
"presets": ["react-native"],
"plugins": [
"transform-decorators-legacy",
[
"module-resolver",
{
"root": ["./app"],
"extensions": [".android.js", ".ios.js", ".js"]
}
]
]
}
I'm still not sure how we can detect which file to load (.android.js or .ios.js). It seems we'll need to add a custom react-native configuration to do that. But even if we do that, I'm not sure yet how to detect the platform react-native is actually using.
@tleunen I don't think this module should do the detection tho unless there is a reason to do so. react native packager handles this correctly.
I think I found a way to tackle this issue.
Until now my way to make the plugin work was to add an empty index.js next to the two index.android.js and index.ios.js. That way, module-resolver will 'pick' the index.js file. When requiring a module without any extension with the RN packager, it will try to find a .platform.js file first then fallback to the .js one.
The solution I propose is to add a configuration option to the plugin like stripExtensions : [".ios.js", ".android.js"] to force the resolver to remove those extensions.
The configuration for a RN project could look like :
json
[
"module-resolver",
{
"root": ["./src"],
"extensions": [".js", ".ios.js", ".android.js"],
"stripExtensions" : [".ios.js", ".android.js"]
}
]
With the help of @MatthieuLemoine, we finally landed a new version which hopefully should finally fix the issue for React Native. So please use [email protected] and report if you see errors.
Please read this to see how to setup for React Native: https://github.com/tleunen/babel-plugin-module-resolver#usage-with-react-native
Thank you.
I would suggest using this with React Native:
https://medium.com/beqode/fixing-import-path-hell-react-native-eslint-vs-code-3d04de9762b6