hoodsy
hoodsy

Reputation: 914

Local require() paths for React-Native

I am looking for a convenient way to access files in the root of my application while avoiding require() strings that look like:

require('../../../../myModule')

There are some good solutions out there for Node (https://gist.github.com/branneman/8048520) but I haven't seen a way to use global variables in React Native.

Does anyone have a clean solution to this problem?

Upvotes: 12

Views: 15705

Answers (5)

pedro.goes
pedro.goes

Reputation: 41

Complementing @Tiagojdferreira

You can use his solution with babel-plugin-module-resolver library.

Install with:

npm install --save-dev babel-plugin-module-resolver

Configure .babelrc adding plugins property like this:

{
  "presets": ["react-native"],
  "plugins": [
    ["module-resolver", {
      "alias": {
        "@src": "MyApp/src",
        "@otherAlias": "MyApp/src/other/path",
      }
    }]
  ]
}

Usage:

require('@src/utils/moment-twitter');

Hope this helps!

Upvotes: 4

Anil
Anil

Reputation: 21910

You can mark a directory as a package by adding a package.json within the root directory you want to resolve.

e.g:

- app
    - package.json     // ← Add this package.json file
    - config
    - components
    - ... (etc)

package.json should look like this:

{ "name": "app" }

Restart your packager

react-native start --reset-cache

Now you can use the following in all of you project files:

import store from 'app/config/store';
import Button from 'app/components/Button';

You can use this same method across other directories in your project, I don't think this works via require, although image paths seemed work.


As noted in the comments, you may lose auto-complete in your editor (VSCode).

For Jetbrains IDE's there are some ongoing tickets here:

This might help with Jetbrains IDE's in the meantime.

// A slash may allow auto-complete to work in your IDE (but will fail to resolve)
import Button from '/app/components/Button'; // Cannot be resolved

Upvotes: 10

Tiagojdferreira
Tiagojdferreira

Reputation: 1122

From Marc Shilling's answer on https://github.com/facebook/react-native/issues/3099

You can use an absolute path on imports/requires:

import {ProximaNovaText} from 'MyApp/src/components'; require('MyApp/src/utils/moment-twitter');

where 'MyApp' is whatever name you registered in your index.ios.js file

Note for VS Code: This works, but be warned that you might lose intellisense and cmd/ctrl + click. Thanks Johan for the info about CS code

Upvotes: 16

DoanND
DoanND

Reputation: 674

Put code below on top of your myModule file:

/**
 * @providesModule myModule
 */

Then you can use require('myModule') in any other files.

Upvotes: 6

deanmcpherson
deanmcpherson

Reputation: 748

You can use global variables in react native, same as node, properties defined on global are accessible globally.

e.g.

global.foo = "blah";
console.log(foo); //logs "blah"

Most of the node solutions in the gist above should work correctly.

One I've used in the past is defining a global function at the top directory level, usually on the first line like

global.rootRequire = function(path) { return require(path); }

Which simply allows deeply nested requires to be from the root, and avoids all of the ../../ business.

However the other comment is true, if this is really an issue, there is probably something structurally deficient with the project.

Upvotes: 0

Related Questions