This repository has been archived by the owner. It is now read-only.

Importing files outside main directory #232

Closed
mmahalwy opened this Issue Jun 1, 2017 · 20 comments

Comments

Projects
None yet
@mmahalwy

mmahalwy commented Jun 1, 2017

Where I have a directory for mobile and a directory for web which I'd like to share some common code (utils, etc). Currently, if I import a file outside the root directory of my generated app (outside where App.js is located), I get an error with no file found.

Is this by design? Will this be supported in the future and is this an Expo limitation or RN?

Thanks

@brentvatne

This comment has been minimized.

Member

brentvatne commented Jun 2, 2017

this is a behavior of the react-native packager: facebook/react-native#12241

@brentvatne brentvatne closed this Jun 2, 2017

@mmahalwy

This comment has been minimized.

mmahalwy commented Jun 6, 2017

@brentvatne thanks for the reply. Will this solution work with Expo?
facebook/react-native#12241 (comment)

@brentvatne

This comment has been minimized.

Member

brentvatne commented Jun 6, 2017

why not try it and find out? :P

yes

@kylebebak

This comment has been minimized.

kylebebak commented Jul 12, 2017

@brentvatne
The solution @mmahalwy mentioned, i.e. creating rn-cli.config.js in the root of my project and using it to add the parent directory as a project root, doesn't work for me with Expo 18.

Wondering if I'm doing something wrong or whether this doesn't work anymore.

@doque

This comment has been minimized.

doque commented Jul 14, 2017

Can confirm that this solution does not work. There is currently no way of importing a file from outside the app directory. Using symlinks doesn't work either.

@RobertWSaunders

This comment has been minimized.

RobertWSaunders commented Jul 18, 2017

One suggestion and workaround I will add is that you could bundle the common files into a npm package and publish it on the npm registry, then you can add it as a dependency to your projects.

@brentvatne

This comment has been minimized.

Member

brentvatne commented Jul 18, 2017

Metro Bundler, which is used by React Native as the packager (the React Native equivalent to Webpack) doesn't support symlinks. As for rn-cli.config.js, it does still work but it's just hard to configure -- we use it on our internal "monorepo" in order to load local versions of our npm packages at Expo. Make sure in app.json, under "expo", you have:

"packagerOpts": {
    "projectRoots": "",
    "assetExts": ["ttf"],
    "config": "rn-cli.config.js"
 },

An example of a rn-cli.config.js:

const path = require('path');

module.exports = {
  getProjectRoots() {
    return [path.join(__dirname, '..', 'other-dir'), __dirname];
  }
};

There really needs to be some better documentation on this :( If someone gets it working, can you write it up?

@robdonn

This comment has been minimized.

robdonn commented Aug 6, 2017

@brentvatne I can't seem to get the packager to accept the other root directories. How do you import them? Do you need to reference the path or just call the component itself?

1 - import 'component' from '../other-dir/component'
2 - import 'component' from 'component'

I'm trying to get a monorepo working similar to yours but I just can't seem to crack this.

My project directory

- apps
-- native (CRNA root)
--- app.json
--- index.js
--- package.json
- components
-- component-1
--- index.js
--- package.json
-- component-2
--- index.js
--- package.json
lerna.json
package.json

app.json

{
  "expo": {
    "sdkVersion": "19.0.0"
  },
  "packagerOpts": {
    "projectRoots": "",
    "config": "rn-cli.config.js"
 }
}

rn-cli.config.js

const path = require('path');

module.exports = {
  getProjectRoots() {
    return [
      path.join(__dirname, '..', '..', 'components'),
      __dirname
    ];
  }
};
@robdonn

This comment has been minimized.

robdonn commented Aug 6, 2017

Nevermind! I'm an idiot! I misunderstood "under expo" in the app.json - It's all working now.

app.json

{
  "expo": {
    "sdkVersion": "19.0.0",
    "packagerOpts": {
      "projectRoots": "",
      "config": "rn-cli.config.js"
    }
  }
}
@dariocravero

This comment has been minimized.

dariocravero commented Sep 25, 2017

@robdonn @brentvatne did this work for you when the module used react and react-native as peer dependencies? After updating to the latest everything (my project had a very old crna-scripts), rn-cli.config.js was being accepted with that config but no matter what I tried, it kept on failing to recognise the linked module.

There's nothing fancy going on with the library (https://github.com/viewsdx/keyboard-avoiding-and-dismissing-view), just one file that exports a component and imports react and some stuff from react-native. Both, react and react-native are marked as peerDependencies and in the latest yarn (1.1.0) they don't get installed at all.

Using the config above it picks up the module alright but it fails to load react with Module does not exist in the module map:

screen shot 2017-09-25 at 20 40 25

If react is a dev dependency (with the same dependencies that my app is using), it goes even crazier because of duplicate module definitions:
screen shot 2017-09-25 at 20 43 07

It doesn't matter if my module comes before or after __dirname in getProjectRoots or if I reset the cache in between. The moment the module is linked it goes boom. :(

It is important to say that it works fine if my linked module doesn't use react, react-native or any other dependency that the project I'm linking from uses.

I wonder if anyone ran into this and got around it somehow?

Do you reckon I should be posting this at facebook/metro/issues/1 instead?

@roblafeve

This comment has been minimized.

roblafeve commented Nov 9, 2017

@dariocravero did you ever find a solution to this problem? This is exactly what I'm up against right now.

@pankaj-arunsingh

This comment has been minimized.

pankaj-arunsingh commented Nov 12, 2017

This is crazy. Please post a solution to this problem if anyone finds it.

@roblafeve

This comment has been minimized.

roblafeve commented Nov 12, 2017

@pankaj-arunsingh I can’t find the original issue where I finally found this but basically add only the external module path you want to import. In my case my module had a dependency on React and React-Native so those are added as extraNodeModules. Hope this helps.

Inside rn-cli.config.js:

var path = require("path");
const metroBundler = require('metro-bundler');

var config = {
  extraNodeModules: {
    "react-native": path.resolve(__dirname, "node_modules/react-native"),
    "react": path.resolve(__dirname, "node_modules/react"),
  },
  getProjectRoots() {
    return [
      // Keep your project directory.
      path.resolve(__dirname),
      path.resolve(__dirname, "../native"), // path to the external module
    ];
  }
}
module.exports = config;
@brentvatne

This comment has been minimized.

Member

brentvatne commented Nov 15, 2017

@pankaj-arunsingh - post to https://github.com/facebook/metro-bundler and be sure to fill out their issue template if you think this should be easier or whatever! @roblafeve's solution works

@dariocravero

This comment has been minimized.

dariocravero commented Dec 2, 2017

In case anyone is stuck with this and until the different issues are fixed, I made a little guide on how to use yarn workspaces with Create React App and Create React Native App (Expo) to share common code across. Hope you find it handy! https://learn.viewsdx.com/how-to-use-yarn-workspaces-with-create-react-app-and-create-react-native-app-expo-to-share-common-ea27bc4bad62 https://medium.com/viewsdx/how-to-use-yarn-workspaces-with-create-react-app-and-create-react-native-app-expo-to-share-common-ea27bc4bad62

@jonasdumas

This comment has been minimized.

jonasdumas commented Dec 19, 2017

@dariocravero your link didn't work ..
But i found it tru the research on medium. Here's the URL that works for me:
https://medium.com/viewsdx/how-to-use-yarn-workspaces-with-create-react-app-and-create-react-native-app-expo-to-share-common-ea27bc4bad62

@dariocravero

This comment has been minimized.

dariocravero commented Dec 19, 2017

Thanks @jonasdumas, we unlinked that domain from medium and I forgot to update the link here!

@dalinarkholin

This comment has been minimized.

dalinarkholin commented Dec 28, 2017

@dariocravero I got it working using your guide, however the nature of my project requires using a classic react-native project. After ejecting are their some steps to get things working?

Let me know thanks!

@dalinarkholin

This comment has been minimized.

dalinarkholin commented Dec 30, 2017

@dariocravero and anyone using his crna-make-symlinks-for-yarn-workspaces module, if you are running a classic react native project(or a ejected crna project) you can remove link('expo', root, from); from the script to prevent errors on a second call of it. I am personally running the script on every react-native start so that I don't have to worry about it. Without making that change I would get yelled at.

@exhibition315

This comment has been minimized.

exhibition315 commented Jun 4, 2018

@roblafeve your solution is working!!!
I add "node_modules/redux" in extraNodeModules, it work very well!!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.