tleunen / babel-plugin-module-resolver

Custom module resolver plugin for Babel
MIT License
3.45k stars 205 forks source link

no work on react native #332

Open hvmien opened 5 years ago

hvmien commented 5 years ago

I have done step by step : Install the plugin: step1:$ npm install --save-dev babel-plugin-module-resolver step2: Specify the plugin in your .babelrc with the custom root or alias. Here's an example:

{ "plugins": [ ["module-resolver", { "root": ["./src"], "alias": { "test": "./test", "underscore": "lodash" } }] ] } and have done npm reset, clean cache. But it not working! everyone help me! Thanks.

kuerbi commented 5 years ago

I had the same problem. This is what works for me.

package.json

{
  name: "MyApp",
  ...
}

.babelrc

plugins: [
  ["module-resolver", {
    "root": ["./src"],
    "alias": {
      "@screens": "MyApp/src/screens",
    }
  }]
]

hope this helps

rommyarb commented 5 years ago

I have done step by step : Install the plugin: step1:$ npm install --save-dev babel-plugin-module-resolver step2: Specify the plugin in your .babelrc with the custom root or alias. Here's an example:

{ "plugins": [ ["module-resolver", { "root": ["./src"], "alias": { "test": "./test", "underscore": "lodash" } }] ] } and have done npm reset, clean cache. But it not working! everyone help me! Thanks.

Can I see your complete .babelrc file?

aohua commented 5 years ago

kuerbi's solution works for me, but not sure if the eslint and vscode will work properly.

smooJitter commented 5 years ago

@AOHUA that's my problem. It worked fine until i updated vscode ESLint. The resolution works but the linting doesn't

aohua commented 5 years ago

@smooJitter This works for me, but seems my jest test is broken. .eslintrc.js

settings: {
    'import/resolver': {
      'babel-module': {
        extensions: ['.js', '.ios.js', '.android.js', '.json'],
        alias: {
          '@Components': './App/Components',
          '@Navigation': './App/Navigation',
          '@Constants': './App/Constants',
          '@Features': './App/Features',
          '@Services': './App/Services',
          '@Fixtures': './App/Fixtures',
          '@Themes': './App/Themes',
          '@Config': './App/Config',
          '@Sagas': './App/Sagas',
          '@Redux': './App/Redux',
          '@Types': './App/Types',
          '@I18n': './App/I18n',
          '@Lib': './App/Lib',
        },
      },
    },
  },

babel.config.js

const MODULE_RESOLVER = [
  'module-resolver',
  {
    extensions: ['.js', '.ios.js', '.android.js', '.json'],
    alias: {
      '@Components': './App/Components',
      '@Navigation': './App/Navigation',
      '@Constants': './App/Constants',
      '@Features': './App/Features',
      '@Services': './App/Services',
      '@Fixtures': './App/Fixtures',
      '@Themes': './App/Themes',
      '@Config': './App/Config',
      '@Sagas': './App/Sagas',
      '@Redux': './App/Redux',
      '@Types': './App/Types',
      '@I18n': './App/I18n',
      '@Lib': './App/Lib',
    },
  },
];
module.exports = {
  plugins: [MODULE_RESOLVER],
  presets: ['module:metro-react-native-babel-preset'],
  env: {
    production: {
      plugins: ['ignite-ignore-reactotron', MODULE_RESOLVER],
    },
  },
};

jsconfig.js

{
    "compilerOptions": {
      "baseUrl": ".",
      "paths": {
        "@Components/*": ["App/Components/*"],
        "@Navigation/*": ["App/Navigation/*"],
        "@Constants/*": ["App/Constants/*"],
        "@Features/*": ["App/Features/*"],
        "@Fixtures/*": ["App/Fixtures/*"],
        "@Services/*": ["./App/Services/*"],
        "@Themes": ["App/Themes"],
        "@Config/*": ["App/Config/*"],
        "@Sagas": ["./App/Sagas"],
        "@Redux/*": ["App/Redux/*"],
        "@Types": ["App/Types"],
        "@I18n": ["App/I18n"],
        "@Lib/*": ["App/Lib/*"],
      }
    }
  }
evanAtFetchly commented 5 years ago

I got mine to work by using @AOHUA 's example. What did it was removing the "root" setting and then just doing the path to each subdirectory.

// babel.config.js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        extensions: [".ios.js", ".android.js", ".js", ".json"],
        alias: {
          assets: './app/assets',
          components: './app/components',
          data: './app/data',
          appredux: './app/redux',
          screens: './app/screens',
          styles: './app/styles',
          utils: './app/utils',
        },
      },
    ],
  ],
}
// .eslintrc
...
"settings": {
    "import/resolver": {
      "babel-module": {
        "alias": {
          "assets": "./app/assets",
          "components": "./app/components",
          "data": "./app/data",
          "appredux": "./app/redux",
          "screens": "./app/screens",
          "styles": "./app/styles",
          "utils": "./app/utils"
        }
      }
    }
  },
...

For VSCode path completion:

// jsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": [
        "app/*"
      ],
    }
  },
}
chuttam commented 5 years ago

Aliases work just fine. Like @evanAtFetchly , I too removed root altogether because it didn't seem to make a difference.


React Native app created via react-native init.

babelrc.js

const commonPlugins = [
  [
    require.resolve('babel-plugin-module-resolver'),
    {
      extensions: ['.ios.js', '.android.js', '.js', '.json'],
      root: ['./src'],
    },
  ],
];

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [...commonPlugins],
};

File widget.js is in ./src/somefolder/

The following line:
import Widget from 'somefolder/widget';
goes kaboom with an "Unable to resolve module" error.

By my interpretation of the documentation, this import should find Widget in ./src/somefolder/widget, but perhaps I've understood incorrectly?

josecarlosns commented 5 years ago

I ran into this issue just now, and what solved it for me was to set the extensions option of the plugin, which only makes sense: the root and alias works just fine, but these options only set what the imports will resolve to, its the extensions option that defines which files the plugin will actually get the imports to resolve, so the plugin will not resolve imports on files whose extensions are not on the extensions list (I don't know if this option has any defaults if not defined, at least I couldn't find anything in the docs). My point is: the plugin will not resolve imports on any JSX/TSX file if you don't explicitly define it in extensions.

In my case, since I'm using React Native with Typescript, my Babel configuration looks like this:

babel.config.js

{
  plugins: [
   [
      'module-resolver',
      {
        root: ['./app/src'],
        extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
        alias: {
          assets: './app/assets',
          test: './app/test'
        }
      }
    ]
  ]
}

I hope it helps, cheers :smile: :+1:

xjq7 commented 5 years ago

my RN 0.60.5+TypeScript project tsconfig.json

{
    "compilerOptions": {
        "baseUrl": ".", // all paths are relative to the baseUrl
        "paths": {
            "@utils/*": ["src/utils/*"],
            "@screen/*": ["src/screen/*"],
            "@store/*": ["src/mobx/*"],
            "@component/*": ["src/component/*"],
            "@common/*": ["src/common/*"],
            "@apollo/*": ["src/apollo/*"]
        },
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "isolatedModules": true,
        "jsx": "react",
        "lib": ["es6"],
        "moduleResolution": "node",
        "noEmit": true,
        "strict": true,
        "target": "esnext",
        "resolveJsonModule": true,
        "experimentalDecorators": true
    },
    "exclude": ["node_modules", "babel.config.js", "metro.config.js", "jest.config.js"]
}

package.json

++"babel-plugin-module-resolver": "^3.2.0",

..babelrc

{
    "presets": ["module:metro-react-native-babel-preset"],
    "plugins": [
        [
            "module-resolver",
            {
                "alias": {
                    "@utils": "./src/utils",
                    "@screen": "./src/screen",
                    "@store/*": ["src/mobx"],
                    "@component/*": ["src/component"],
                    "@common/*": ["src/common"],
                    "@apollo/*": ["src/apollo"]
                }
            }
        ],
        [
            "@babel/plugin-proposal-decorators",
            {
                "legacy": true
            }
        ]
    ]
}

I hope it can help you

Aleksefo commented 4 years ago

I'm using React Native 0.61.2 + TypeScript and neither of the above solutions works.

Getting: bundling failed: Error: Unable to resolve module '../../screens/HomeScreen' from 'src/navigation/AppNavigator.tsx': no matter what the babel or tsconfig settings.

dclipca commented 4 years ago

I would suggest using this with React Native: https://medium.com/beqode/fixing-import-path-hell-react-native-eslint-vs-code-3d04de9762b6

0x1ad2 commented 4 years ago

Be sure to use the absolute path for your aliases, I assumed that it automagically would grab the root path as root for the aliases as well.

This is what my babel.config.js looks like (RN 0.62)

    api.cache(true);

    const presets = ['module:metro-react-native-babel-preset'];
    const plugins = [
      [
        'module-resolver',
        {
          root: ['./src'],
          alias: {
            recoveryComponents: './src/components',
            assets: './src/assets',
            screens: './src/screens',
          },
          extensions: ['.ios.js', '.android.js', '.js', '.json'],
        },
      ],
    ];

    return {
      presets,
      plugins,
    };
  };
8of commented 4 years ago

For anyone who uses TypeScript and just wants to use import with absolute paths without aliases.

Assuming all of your code folders are inside of src.

Insert "baseUrl": "src" in compilerOptions object inside tsconfig.json.

Now you can use absolute paths in imports.

mdedys commented 3 years ago

I had the same problem. This is what works for me.

package.json

{
  name: "MyApp",
  ...
}

.babelrc

plugins: [
  ["module-resolver", {
    "root": ["./src"],
    "alias": {
      "@screens": "MyApp/src/screens",
    }
  }]
]

hope this helps

This solved my problem within a monorepo. Using the package.json name at the beginning of the path in alias

muzhaqi16 commented 2 years ago

Working fine with "react-native": "0.66.2" and "babel-plugin-module-resolver": "^4.1.0",