Hey there. This is not an issue per say, more a cry for help.
Have you by some crazy chance attempted to use this plugin with React Native? It simply just doesn't seem to work. I opened a Stack Overflow issue about this. Any help would be greatly appreciated! If you're at a loss as I am, please feel free to ignore and close this issue.
To be honest, I never tried it on react-native because I still never used Native yet.
But from the error you're reporting
Unable to resolve module app/components/MyComponent from .... Invalid directory /Users/node_modules/app/components/MyComponent.
It looks like the plugin doesn't transform the path correctly. The path points to Users/node_modules. It looks very weird.
Do you have by any chance a small project to easily reproduce the issue?
Hey there, I created a test project: https://github.com/adamterlson/babeltest
Thank you for your help!
By the way, if you like React and have interest in native app development at all, check out React Native. It's super awesome. :)
I am very interested in React Native ;-) Just couldn't have the time to really dig into it yet.
Thanks for the setup though, I'll try to see what I can do to add the RN support.
After a quick investigation, it seems the plugin is never used. That's why the path is not updated and RN cannot find the module at app/MyComponent.
I'm still not sure yet how to properly debug the babel config/loader inside react native.
Yeah, I am not sure how to do that either. Wonder why it's not used... Hmmm. Thanks for looking into it though!
@adamterlson i don't believe it will work with react native because react-native has its own module aliasing and resolution approach based on their own dependency graph tools
see:
https://github.com/facebook/fbjs#usage
https://github.com/facebook/fbjs/blob/master/scripts/babel/rewrite-modules.js
@datapimp Well that's a bummer. Good find, thank you for the information!
So I take it then that the fbjs babel rewrite-modules comes first before the user-specified babel plugins? Sure would be nice if it were possible to reverse that order....
Yep, from my investigation, it comes first so the plugin is not even executed because the path is not correct. I opened a ticket in react-native to see what we could do. https://github.com/facebook/react-native/issues/6118
Awesome, thank you very much @tleunen.
So after reading through the issue thread (facebook/react-native#6118) it seems not part of the game plan to add this before/after hook any time soon, and at any rate, the issue is not with module-alias.
They recommend not to use ProvidesModule; however, I needed to move forward so I thought I'd share what I did in case anyone else finds this thread and wants to live dangerously.
First, I'm assuming that once fbjs is removed from RN (which is planned and probably why they don't want people using providesModule) then module-alias will work as expected. I did some experimenting and found that providesModule doesn't just take "MyModule" as in the example, you can give it any string, including something that looks like a path that corresponds to its location:
/*
* @providesModule app/redux/modules/user
*/
In this way, I can actually require this module from a component in the precise way that module-alias would allow:
import * as UserActions from 'app/redux/modules/user';
So, once fbjs goes away, I'll delete all the providesModule lines and it should just keep working with an alias set up for "app".
That's the theory, anyway. Thank you @tleunen and @datapimp for your help!
Hmm.. Maybe.. If someone can test it. Otherwise I'll try to find some time to give it a try
@tleunen, @adamterlson It still does not work. The RN packager somehow interferes and tries to resolve relative to node_modules/react-native/packager.
I added this to my .babelrc:
"plugins": [
["babel-plugin-module-alias", [
{"src": "./foo", "expose": "foo"}
]]
]
And this to index.android.js:
import 'foo/bar'
The result:

For comparison: if I add import 'foo/bar' to a file one level down, e.g. src/index.js, the error messages reflects that (the two dots are new):

So if we could somehow prevent the RN packager from adding the node_modules/react-native/packager bit β¦
Sorry that I am so non-technical here. I just do not have sufficient understanding of what is going on here to be more precise.
I tested with RN 21.
Figured out how that path gets in there: It is just because react-native/packager/launchPackager.command changes the cwd. If I manually start the packager from the project dir (./node_modules/react-native/packager/packager.sh start), a similar error message appears β with the correct path, however:

Wild guess: when the RN packager builds the in-memory fs for JavaScript it only includes the code that it considers relevant. But at that point in time, _babel-plugin-module-alias_ hadn't had the chance to transform the path yet. So the packager thinks that the module isn't there.
Is there any solution we can do?
It works fine for me with RN 0.24 on Linux.
My .babelrc is
{
"presets": [
"react-native"
],
"plugins": [
["babel-plugin-module-alias", [
{ "src": "./src/lib", "expose": "lib" }
]]
]
}
And it works with just a regular npm start. I guess it's completely fixed now?
That's awesome! @adamterlson can you confirm it works for you as well?
Yup! Confirmed! π
@adamterlson @thatsmydoing: You used the babel-preset-react-native npm-package, correct?
Did you by any chance also make Flow understand how to use this package?
Yes, react-native preset is the only other thing I have in my babelrc. I haven't really tried to use flow, so I can't help there
@consideRatio Sorry I haven't had much luck using flow for RN. I get all sorts of problems. Sorry I can't help!
I got this to work with Flow by using this package and then _additionally_ symlinking my src file into node_modules. This plugin satisfies the packager, and the symlink satisfies Flow.
Previously this module was worked for me with RN 0.25.
But when I upgrade to React Native 0.27.2 with React 15.1.0, it didn't work again.

Had anyone confirmed with RN 0.27?
Edit:
I have upgrade to latest version, and the problem still exist.
Below is my .babelrc
{
"passPerPreset": true,
"presets": [
{
"plugins": [
"./server/schema/babelRelayPlugin"
]
},
"react-native"
],
"plugins": [
"transform-decorators-legacy",
["module-alias", [
{ "src": "./src/components", "expose": "~shared-components" },
{ "src": "./src/constants", "expose": "~constants" },
{ "src": "./src/helpers", "expose": "~utils" },
{ "src": "./src/modules", "expose": "~modules" },
{ "src": "assets", "expose": "~assets" }
]]
]
}
Edit:
I think there's a correlation with https://github.com/facebook/react-native/issues/6118#issuecomment-215885029)
Could you try with the previous version to see if it's a new issue with the latest version of the plugin?
It's work on babel-plugin-module-alias version 1.4 with RN 0.25 (+ React 0.14).
And it doesn't work on babel-plugin-module-alias version 1.4 with RN 0.27.2 and babel-plugin-module-alias latest version (1.5) with RN 0.27.2. FYI RN with version >= 0.27 must use React 15, which I guess it use different providesModules (https://github.com/facebook/react-native/issues/6118#issuecomment-215885029)
I don't know what I did exactly, but now I don't get this issue again :tada: LOL
@pewh Can you share your versions on package.json? I'm having this issue now with react-native: 0.31.0 and babel-plugin-module-alias: 1.6.0, my .babelrc looks like this:
{
"presets": [
"react-native"
],
"plugins": [
["module-alias", [
{ "src": "./src/foo", "expose": "foo" },
{ "src": "./src/bar", "expose": "bar" }
]]
]
}
When I try import file from 'foo/file' it's looking within /node_modules still
UPDATE: Deleted the .babelrc file to make sure RN packager was reading it, got the expected file not found error, when I reincorporated it, worked. :l
Still having the same problem... Removing .babelrc doesn't even throw an error. We randomly experience this error after restarting/rebuilding the system.
What we have found out helps is replacing _a few_ of the file references to their relative paths, until it starts to work again. After that we revert these changes and everything still works as expected.
well, looks like for me it's working, here is my .babelrc
{
"presets": [
"react-native"
],
"plugins": [
["module-resolver", {
"root": ["./src"],
"alias": {
"components": "./src/views/components",
"themes": "./src/views/themes"
}
}]
],
"env": {
"development": {
"sourceMaps": "inline"
}
}
}
and also I added source ~/.bash_profile to xcode project settings in 'bundle react native code and images' section
upd: sorry, checked it again: no it's still crashing with "Unable to resolve module ...node_modules/react-native/packager/{alias_way}", still looking for a way to start react-native from ios, not from root directory with 'npm start'
Any news? It's still crashing on RN0.35 :(
Some people are saying it's working. If it's not, could you please provide a small project to reproduce the issue? I currently don't have any RN project so it will help a lot
It seems a caching problem on react-native side... :(
https://github.com/facebook/react-native/issues/8249
@mmazzarolo You may be aware of this already, but I was able to effect a nice work around in my project, without using ProvidesModule, with an additional package.json file.
I discovered that if you put a package.json file somewhere up in the folder hierarchy, you can add a "name" key and refer to that name in your require paths.
e.g. package.json located in /app:
{
"name": "custom"
}
Then in /app/components/MyComponentA:
import MyComponentB from 'custom/components/MyComponentB';
Maybe this would satisfy your use case?
@adamterlson, yes, I'm already aware of that trick but thank you anyway man :+1:
However I'd prefer using the same babel setting and package (this one) on my node/react/react-native projects at work.
Btw the package is working fine so far on react-native if I reset the server with the -- --reset-cache, which means that it is a caching issue on the react-native side (I guess...).
Ah okay, glad you got it working π
Report: Get crashing in RN 0.38, if run react-native run-ios. If run npm start -- --reset-cache it works fine. Still I'm waiting for an elegant solution to run react-native run-ios.
Canβt get this working. Iβve tried about 3 separate times.
{
"plugins": [
[
"module-resolver",
{
"alias": {
"components": "./src/components",
},
"root": [
"./"
],
}
]
],
"presets": [
"react-native-stage-0"
]
}
Iβve tried specifying with root and without it. Is root required? Doesnβt say anything in the README about what is required and what is not.
{
...,
"react-native": "^0.39.2",
"babel-plugin-module-resolver": "^2.5.0",
}
Importing as
import Foo from 'components/foo';
@kirkstrobeck
here is working config, I added '@' so it is compatible with react-natives package.json linking
https://github.com/igorlimansky/react-native-redux-boilerplate/blob/master/.babelrc
@kirkstrobeck If you're interested we're using this lib at my current workplace and it's working correctly on all our apps (Node - React - React-Native).
Our super simple setup for React-Native is the following:
// .babelrc
{
"presets": ["react-native"],
"plugins": [
["module-resolver", { "alias": { "src": "./src" } }]
]
}
I'm using RN 0.42.3 and I can't get this to work. Also a reasonably simple setup:
// .babelrc
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"root": ["./src"],
"alias": {
"app": "./src/app",
"assets": "./src/assets"
}
}]
]
}
Any recent help on this?
@ozzyknox i have similar problem
+1
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"root": ["./"],
"alias": {
"src": "./src",
"resource": "./resource"
}
}]
]
}
module resolver try resolve in
/Users/%username%/Documents/%app_name%/node_modules/react-native/packager/
why?
I'm using a config similar to @mmazzarolo's and it's working great.
@ozzyknox @Maxim-Chugaev did you try without the root key?
Also be sure to reset the packager cache. It can be done with react-native start --reset-cache
On RN 0.41.2, I had the same issue than @Maxim-Chugaev (module resolver looking in node_modules/react-native/packager).
Reseting the packager cache as suggested by @jeanregisser made it work.
Resetting packager cache works on me too
RN 0.42.3
@peto85 @sercanov It's not working for me (RN 0.42.3). May I ask what's in your .babelrc file?
For @svicalifornia and folk wanting to get this up and running with react-native, running babel-plugin-module-resolver version 2.7.0 and react-native 0.43.0
yarn add babel-plugin-module-resolver --dev
Note - this is _not_ "babel-plugin-module-alias", which is capped at version 1.6.0
{
"presets": [
"react-native"
],
"plugins": [
[
"module-resolver",
{
"root": ["./src"],
"alias": {
"components": "./components"
}
}
]
]
}
Note -This tool goes under plugins, and _not_ presets.
With the above configuration it assumes a directory structure of:
.YourApplication
βββ android
βββ app.json
βββ index.android.js
βββ index.ios.js
βββ ios
βββ node_modules
βββ package.json
βββ readme.md
βββ src
βββ components // Your custom components that we provided an alias for
βββ button
βββ index.js
βββ tests
βββ yarn-error.log
βββ yarn.lock
You can then import your custom components anywhere within your react-native application with:
import Button from 'components/button';
Note - You _may_ need to clear your cache in some cases:
npm run start -- --reset-cache
@svicalifornia my .babelrc is quite simple:
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"root": ["./"],
"alias": {
"src": "./src"
}
}]
]
}
Still running into this issue when using require('myAliasName') and my .baberc looks very similar to peto85's
Still having this issue using RN 0.44 + webpack
@AlanFoster I used your solution and it's great until it fails.
Resetting the cache (npm run start -- --reset-cache) works for me but if I start the packager from xCode then it fails again.
Could you explain more about: _"Note - You may need to clear your cache in some cases:"_
You might consider using Haul instead of react-native-packager (or metro-bundler as it's called now). It doesn't require resetting cache to work with this plugin.
Same issue here, I'm on windows...
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"root": ["./src", "./core"]
}]
]
}
I think the core of the issue is that when React.xcodeproj automatically launches the Packager, it does so from the directory of the packager. Any sane person is going to launch it from the root of their project, and that is where all of the module-resolver paths are starting from. To compound the issue, once you've launched it the "incorrect" way once, then there are cached paths that interfere with you once you try to launch it elsewhere. That's why --reset-cache is a popular answer to the problem, although it doesn't fix the core issue.
Here's what I did to sleep better at night:
1) Leave React.xcodeproj and everything else in node_modules alone.
2) Make a copy of launchPackager.command and packager.sh (from /node_modules/react-native/packager) and drop them into my project source tree
3) Edit packager.sh so that it changes to your project root dir and then launches the react-native cli from there. ALSO, I added the --reset-cache parameter so that anytime I want to reset the cache I just need to close out the long-standing React Packager terminal instance. The next program run will relaunch and reset the cache.
The new packager.sh (adjust your relative path from THIS_DIR to your project root as necessary. $THIS_DIR will point to wherever you put the packager.sh file):
THIS_DIR=$(dirname "$0")
pushd "$THIS_DIR/../../../"
pwd
node "./node_modules/react-native/local-cli/cli.js" start --reset-cache "$@"
popd
4) Here's the key: We want to launch the packager before React.xcodeproj does it automatically. So, what I did was put a Pre-Action in my Scheme in Xcode. Edit Scheme -> Run -> Pre-Actions, Then add the following for the script (copied from React.xcodeproj, but with the path to launchPackager.command changed)
if [ -z "${RCT_NO_LAUNCH_PACKAGER+xxx}" ] ; then
if nc -w 5 -z localhost 8081 ; then
if ! curl -s "http://localhost:8081/status" | grep -q "packager-status:running" ; then
echo "Port 8081 already in use, packager is either not running or not running correctly"
exit 2
fi
else
open "$SRCROOT/../src/platforms/native/launchPackager.command" || echo "Can't start packager automatically"
fi
fi
Please note that your path to launchPackager.command will likely be different.
After doing all of this, now my module-resolver settings all work correctly when I let Xcode launch the packager. Prior to this, I was just always keeping it launched from my own terminal window and anytime I forgot to do that I would have to close out the auto-launched copy of packager and run a --reset-cache to get things working again. Easy enough for me to do, but a hassle and not easy to explain to other dev's working on the project.
Next step: convince the React-native guys to change their launch point of the packager so that none of this is necessary.
For me works this one:
step 1
watchman watch-del-all && rm -rf $TMPDIR/react-* && rm -rf node_modules/ && npm cache clean && npm install && npm start -- --reset-cache
step 2
Reload iphone simulator, for my case it is
Cmd R
Just take note:
You can run project only in this way npm start.
Command react-native run-ios does not work with aliases.
I cannot get this to work with react-native run-android either (as others have said react-native run-ios does not work) when setting root to ./app. I get an error saying that my application code is trying to import from path_to_project/node_models/react-native/app, which it should not be. So i get around this by setting root to ../../app when i use react-native run-android, however when building my APK i get that the module is trying to import from a different starting point (the correct one). So for building my APK i have to set root to ./app.
So for now this is what my .babelrc file looks like:
{
"presets": ["react-native"],
"env": {
"production": {
"plugins": [
["module-resolver", {
"root": ["./app"],
"extensions": [".js", ".ios.js", ".android.js"],
"alias": {
"MyActions": "./app/actions",
...
}
}
]
]
},
"development": {
"plugins": [
["module-resolver", {
"root": ["../../app"],
"extensions": [".js", ".ios.js", ".android.js"],
"alias": {
"MyActions": "../../app/actions"
}
}]
]
}
},
}
Though this is kind of awkward...
Its not working with "require" fn but works with "import".
.babelrc
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"root": ["./app"],
"alias": {
"~": "/",
"@images": "/images",
"@data": "/data",
"underscore": "lodash"
}
}]
]
}
package.json
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-eslint": "^7.2.3",
"babel-jest": "20.0.3",
"babel-plugin-module-resolver": "^2.7.1",
"babel-preset-react-native": "^2.0.0",
"eslint": "^4.6.1",
"eslint-config-airbnb": "^15.1.0",
"eslint-import-resolver-babel-module": "2.2.1",
"eslint-plugin-babel": "^4.1.2",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-prefer-object-spread": "^1.2.1",
"eslint-plugin-react": "^7.2.1",
"eslint-plugin-react-native": "^3.1.0",
....
}
Works with import at top:
import I18n from '~/localization';
not working with require:
<Image source={require('@images/test.jpg')} />
@tayfunyasar What if you move your require at the top and use the variable in your component instead?
Thanks for your answer @tleunen.
Its still not working with require. I also tried import it, it worked with it.
worked:
import gradientBg from '~/images/test.png';
still not working:
var gradientBg = require('~/images/test.png');
error message:
Unable to resolve module '//images/test.png' from '#MyProjectDir#/app/component/xxx/index.js' could not resolve '//images/test.png' as a folder: it did not contain a package, not an index file
Still not working with the following configuration on windows and react native 0.47.2
{
"presets": ["react-native"],
"plugins": [
[
"module-alias", {
"root": ["./app"],
"alias": {
"screens": "./screens"
},
"extensions": [".js", ".ios.js", ".android.js"]
}
]
]
}
I finally "solved" the problem by adding package.json in the app/screens folder with
{name: "screens"}
and declaring that folder as a local dependency in my main package.json.
@emusgrave after following the steps you have mentioned we got this error in xcode.
"React/RCTLog.h file is not found" please look into that, give us any leads if anyone resolved this error...
I was having the issue where the packager would be looking for babel-plugin-module-resolver aliases inside node_modules/. @emusgrave's comment made me realize I had been using the wrong npm script for start. For some reason, in the old version of my codebase, I had it as:
"start": "./node_modules/react-native/packager/packager.sh",
When I updated RN, that packager/ folder was no longer there, but I realized there was scripts/packager.sh script, so I changed it to:
"start": "./node_modules/react-native/scripts/packager.sh",
This was my mistake. It was this script that was making the packager pick up aliases from inside node_modules/. I was able to solve this by changing it back to:
"start": "node ./node_modules/react-native/local-cli/cli.js start",
Coming way after the battle, but still.
I managed to finally make it work by adding ".js" to the extensions list and clearing the cache when running metro. Below is my .babelrc :
{
"plugins": [
["module-resolver", {
"root": ["./app/**", "./assets/**"],
"extensions": [".js"]
}]
],
"presets": ["react-native"]
}
Then starting metro by running react-native start -- --reset-cache
So if I understand correctly, it is not possible to use this plugin with react-native run-ios? You really have to run react-native start -- --reset-cache every time?
Resetting the cache once did the trick for me.
(tested with RN 0.52.0 and module-resolver babel plugin)
For react-native cli command, the working directory for Babel plugins is a directory ./node_modules/react-native and not the project's root (i.e. where the .babelrc file resides). The result is that module-resolver incorrectly resolves all paths from the misplaced project's root. As a workaround one can rewrite the relative paths a little bit. Each dot "." should be rewritten as "../.." to help with the path resolution.
For instance, the following babel configuration (check root parameter):
// .babelrc
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"root": [".", "./src"]
}]
]
}
should be:
// .babelrc
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"root": [".", "./src", "../..", "../../src"]
}]
]
}
The original paths can be left as they are, as some IDEs (VB Code + RN extension) have their own Metro builder with properly configured project's working directory and no issues with module-resolver babel plugin.
Reporting:
To react native use the package.json fix, after having run
react-native start - --reset-cache
("start": "node./node_modules/react-native/local-cli/cli.js start ")
To reactjs it worked: https://github.com/entwicklerstube/babel-plugin-root-import
Greetings β
@emusgrave could you please show, where you place your files?
I don't get it to work.
I've placed the two files into /ios/-Directory.
My Packager.sh looks like this:
THIS_DIR=$(dirname "$0")
pushd "$THIS_DIR/../"
pwd
node "./node_modules/react-native/local-cli/cli.js" start --reset-cache "$@"
popd
and adjusted the Run-Script like that:

I'm not sure, where the $SRCROOT points to.
I am solve this problem. Just add to metro.config.js attribute resetCache: true
package.json.
{
"name": "myApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"android": "react-native run-android",
"test": "jest"
},
"dependencies": {
"react": "16.8.3",
"react-native": "0.59.4"
},
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/runtime": "^7.4.3",
"@types/jest": "^24.0.11",
"@types/react": "^16.8.13",
"@types/react-native": "^0.57.43",
"@types/react-test-renderer": "^16.8.1",
"babel-jest": "^24.7.1",
"babel-plugin-module-resolver": "^3.2.0",
"jest": "^24.7.1",
"metro-react-native-babel-preset": "^0.53.1",
"react-native-typescript-transformer": "^1.2.12",
"react-test-renderer": "16.8.3",
"ts-jest": "^24.0.2",
"typescript": "^3.4.3"
},
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}
}
metro.config.js. Add resetCache: true
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
resetCache: true
},
}),
},
};
tsconfig.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@components/*": ["components/*"]
},
}
}
babel.config.js
module.exports = {
presets: ["module:metro-react-native-babel-preset"],
plugins: [
[
"module-resolver",
{
root: ["./src"],
extensions: [".tsx"],
alias: {
"@components": "./src/components"
}
}
]
]
};
App.tsx
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React from "react";
import { Component } from "react";
import { Platform, StyleSheet, Text, View } from "react-native";
import Buble from "@components/buble";
const instructions = Platform.select({
ios: "Press Cmd+R to reload,\n" + "Cmd+D or shake for dev menu",
android: "Double tap R on your keyboard to reload,\n" + "Shake or press menu button for dev menu"
});
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native! 200</Text>
<Text style={styles.instructions}>To get started, edit App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>
<Buble />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
}
});
Most helpful comment
@mmazzarolo You may be aware of this already, but I was able to effect a nice work around in my project, without using ProvidesModule, with an additional package.json file.
I discovered that if you put a package.json file somewhere up in the folder hierarchy, you can add a "name" key and refer to that name in your require paths.
e.g. package.json located in /app:
Then in /app/components/MyComponentA:
Maybe this would satisfy your use case?