Can Poyrazoğlu
Can Poyrazoğlu

Reputation: 34780

Cannot resolve module while trying to organize modules in React Native

I'm new to React Native and am trying to organize my React Native classes into modules to get rid of the "import from '../../../" mess. Here's my very simple folder structure:

enter image description here

Following the tutorial at here, I've structured my package.json as this for each folder:

{
    "name": "@foldername"
}

Now, I'm trying to import Page (which is just a component superclass at this time, exported as default in the file):

import Page from '@app/components/core';

But it cannot be resolved. I've also tried:

import Page from '@app/@components/@core';

import { Page } from '@app/@components/@core';

import { Page } from '@app/components/core';

import { Page } from 'app/components/core';

None of them seem to be working. I've also tried them all without the @ sign (removing it from both the package files and import statement), but no avail.

How can I organize my components to work that way (and it would be great if I knew what that @ sign in front does, as I've also seen some tutorials without it)?

Here is my package.json in my root folder if it helps (haven't touched it, it's the way created by react-native init):

{
  "name": "redacted",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.8.3",
    "react-native": "0.59.3"
  },
  "devDependencies": {
    "@babel/core": "^7.4.0",
    "@babel/runtime": "^7.4.2",
    "babel-jest": "^24.5.0",
    "jest": "^24.5.0",
    "metro-react-native-babel-preset": "^0.53.1",
    "react-test-renderer": "16.8.3"
  },
  "jest": {
    "preset": "react-native"
  }
}

Upvotes: 4

Views: 7697

Answers (4)

Michael Derbeyev
Michael Derbeyev

Reputation: 11

In tsconfig.json, add the following :

"compilerOptions": {
    "baseUrl": "app"
...
}

Upvotes: 1

JRK
JRK

Reputation: 3904

If you're using VSCode, Intellisense of the IDE does not recognise just the package.json; include a tsconfig/jsconfig JSON file (TypeScript [ftw]/ JavaScript)

In compilerOptions add :

"paths" : {
    "@alias1*" : ["./alias1/*"],
     .....
  }

For all your aliases. Then the editor should pick up your files.

https://code.visualstudio.com/docs/languages/jsconfig

If you choose not to use VSCode, use Babel:

If your project doesn’t use Webpack - for example if you’re working with React Native, you can use your .babelrc file and a babel plugin to get aliasing set up.

Firstly, you’ll want to install babel-plugin-module-resolver with yarn or npm.

Once you’ve done that, open up your project’s .babelrc file, and under the plugins key, add this:

[
  'module-resolver',
  {
    root: ['./src'],
    alias: {
      myAlias: './src',
    },
  },
];

Or use the package.json in root

Upvotes: 2

Can Poyrazoğlu
Can Poyrazoğlu

Reputation: 34780

It was my bad.

Instead of using it like:

import MyComponent from 'package/path/MyComponent'

I was using:

import MyComponent from 'package/path' (without my class file at the end).

I've imported it correctly (also removed the app package and the @ prefixes and directly referenced components as a package in its package.json file) (including the component name):

import Page from 'components/core/Page';

It worked perfectly.

Upvotes: 1

Gev
Gev

Reputation: 882

add babel-plugin-module-resolver to devDependencies. If you have .babelrc just delete it and add babel.config.js. And add aliases there. It should look like this

function babelConfig(api) {
  if (api) {
    api.cache(false);
  }

  const presets = ['module:metro-react-native-babel-preset'];
  const plugins = [
    [
      'module-resolver',
      {
        alias: {
          appColors: './src/Colors',
          appConstants: './src/Constants',
          components: './src/Components',
          screens: './src/Screens',
          utils: './src/utils'
        },
        cwd: 'babelrc'
      }
    ]
  ];

  return {
    presets,
    plugins
  };
}

module.exports = babelConfig;

Then you can use import like this

import { YourComonent } from 'components';

make sure you have exported as default. Also, don't try to set the alias names with capital letters

This works with the latest react-native (0.59.3).

Here is my devDependencies

devDependencies": {
    "@babel/core": "7.4.0",
    "@babel/runtime": "7.4.2",
    "@react-native-community/eslint-config": "0.0.3",
    "babel-eslint": "8.2.2",
    "babel-jest": "24.5.0",
    "babel-plugin-module-resolver": "^3.2.0",
    "enzyme": "^3.9.0",
    "enzyme-adapter-react-16": "^1.10.0",
    "enzyme-to-json": "^3.3.5",
    "eslint": "5.15.3",
    "eslint-config-airbnb": "16.1.0",
    "eslint-plugin-import": "2.12.0",
    "eslint-plugin-jsx-a11y": "6.0.3",
    "eslint-plugin-react": "7.9.1",
    "eslint-plugin-react-native": "3.2.1",
    "jest": "24.5.0",
    "metro-react-native-babel-preset": "0.53.1",
    "react-test-renderer": "16.8.3"
  },

Upvotes: 5

Related Questions