React-Native import files outside of main directory
Asked Answered
R

5

11

I am trying to make a demo app for some components using Expo and react-native. (Or I also could use regular React-Native)

My problem is I cannot import files outside of the demo app

Here is the structure I have
|-- Components/ | |-- libs | |-- node_modules | |-- index.js | |-- package.json | |-- demo/ | | |-- node_modules | | |-- App.js | | |-- package.json

Inside of demo/App.js, I am trying to import one of my components from the upper directory but with no luck. All the components are exported in ./index.js

Inside of App.js, I tried : import {MyComponent} from 'Components', import {MyComponent} from '../index', or import {MyComponent} from '../../Components/' but none seem to work.

I got the following type of error Directory /Users/kevin/web/myprojects/Components/index doesn't exist

What Am I doing wrong ?

Rightness answered 3/4, 2017 at 9:30 Comment(2)
try explicitly resolving paths in your App.js. Add this line and check again: app.use('/Components', express.static(__dirname + '/Components/'));Gaberones
Thanks, but I am not using express, I am using [expo.io/]Rightness
S
4

The way the react-native packager works right now, it's just going to scan the roots of your project and below when creating the JavaScript bundle, so it will be really hard to do this.

You basically just need to put the files under the root of your directory. There are some tools out there for syncing files from another directory into a directory under the root so you could use one of those if you really need to.

Some people are working on ways to make symlinks work with this. Notably, you might look at Haul from Callstack. https://github.com/callstack-io/haul But that isn't integrated into Expo yet.

Statesman answered 3/4, 2017 at 10:35 Comment(5)
Thanks for the explanation, I was afraid I would run into these sorts of things. I ll see what I can do.Rightness
This really sucks in the case that you have a web app and a native app that share some common code. You're forced to depend on the same version of react, which can get into an impossible bind when arises versioning issues with other dependencies. I just got bitten by this.Duhamel
Any solution to this? I am bit by this tooEntwine
@MohamedElMahallawy: the author of this blog post provides a possible solution. Search for "symlink" in that page to find it. It basically involves triggering babel transformations on top-level .js files that have changed, before copying them into a directory accessible to the react-native app.Larimer
Another idea to find a solution : read through the (very long) issue github.com/facebook/react-native/issues/637. It offers a lot of suggestions.Larimer
B
3

Take a look into the Metro configurations, the watchFolder is configured there. And according to its specification is what you want!

watchFolders

Type: Array

Specify any additional (to projectRoot) watch folders, this is used to know which files to watch.

Check the link bellow:

https://facebook.github.io/metro/docs/configuration#watchfolders

Be careful !

As I noted in your question, you have 2 node_modules folders

Having more than one node_modules can break the metro's compilation.

To resolve this situation take a look in the resolver.extraNodeModules configuration in metro config.

https://facebook.github.io/metro/docs/configuration/#extranodemodules

Babushka answered 13/9, 2019 at 10:38 Comment(2)
does link are not working anymoreBlastoff
links were updated, thanks AnthonyBabushka
D
3

You could turn the root folder into a local npm package...

  1. In the root folder, open package.json
  2. Set the name field in package.json
  3. Run npm pack.
  4. Copy the gz tarball name given at the end of the terminal.
  5. Open the directory of your App.js
  6. Run npm install ../NAME_OF_TARBALL_THAT_YOU_COPIED
  7. In the file, do import {MyComponent} from 'NAME_IN_PACKAGE.JSON'
Duodenitis answered 23/2, 2020 at 6:21 Comment(0)
L
2

You can try update metro.config.js (RN 0.69.3)

 const path = require('path');

 module.exports = {
  transformer: {
    getTransformOptions: async () => ({
     transform: {
      experimentalImportSupport: false,
      inlineRequires: true,
    },
  }),
 },
 // options for reading data outside root react-native folder
 projectRoot: __dirname,
 watchFolders: [path.resolve(__dirname, '../')],
};

Merto config docs https://facebook.github.io/metro/docs/configuration#watchfolders

Leotie answered 9/8, 2022 at 7:45 Comment(0)
I
0

You can create a rn-cli.config.js file in demo folder and add the following code:

var path = require("path");
var config = {
    watchFolders: [
     path.resolve(__dirname,"../"),
    ]
}
module.exports = config;

Ref: View options in here

After running react-native run-android or react-native start, if you see this, it worked.

Intendant answered 15/11, 2018 at 4:37 Comment(1)
Doesn't work for react native 0.60+. Check Renan's answer instead.Venicevenin

© 2022 - 2024 — McMap. All rights reserved.