4

This is embarrassing, but I don't know what else to do. I wanted to port my little React Native project to TypeScript, so I created an empty React Native project with TypeScript template, tweaked tsconfig.json to use custom paths such as @app and I tried to run it. It didn't. And this was yesterday, I did some googling, but those who had the same issue suggested to clean the packager, remove node_modules and reinstall packages all over, for example, this one, so I did, and it didn't work.

These are my steps for reinstalling react-native-cli (at first I thought that the problem is with outdated package, it wasn't):

  • npm uninstall -g react-native-cli
  • yarn global add @react-native-community/cli

Those below I followed already that many times, that I don't remember the exact number:

  • npx react-native init MyApp --template react-native-template-typescript
  • yarn add redux redux-logger redux-thunk react-redux
  • yarn add --dev @types/react @types/react-redux @types/redux-logger

And then making changes to tsconfig.json, so it looks likes this ( my changes marked with ->):

{
  "compilerOptions": {
    /* Basic Options */
    "target": "esnext",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "esnext",                       /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "lib": ["dom", "esnext"],                 /* Specify library files to be included in the compilation. */
    "allowJs": true,                          /* Allow javascript files to be compiled. */
    "jsx": "react-native",                    /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    "noEmit": true,                           /* Do not emit outputs. */
    "incremental": true,                      /* Enable incremental compilation */
    "isolatedModules": true,                  /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */

    /* Module Resolution Options */
    "moduleResolution": "node",               /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
->  "baseUrl": "./src",                       /* Base directory to resolve non-absolute module names. */
->  "paths": {                                /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
->    "@app/*": ["./*"]
->  },
    "allowSyntheticDefaultImports": true,     /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */    
  },
  "exclude": [
    "node_modules", "babel.config.js", "metro.config.js", "jest.config.js"
  ]
}

My project structure looks like this:

MyApp
├── ios
├── android
├── src
│   ├── index.tsx
│   ├── constants
│   │   └── app.json
│   ├── support   
│   │   └── store.tsx   
│   └── reducers   
│       └── index.tsx
├── tsconfig.json
├── package.json
├── index.js 
└── [ the rest ]

And when I'm trying to import {initStore} from '@app/support/store' in MyApp/src/index.tsx the Metro gives me the following:

Loading dependency graph, done.
error: bundling failed: Error: Unable to resolve module `@app/support/store` from `src/index.tsx`: @app/support/store could not be found within the project.

Then I tried cleaning with following commands, but it also didn't do any good:

  • watchman watch-del-all && rm -rf $TMPDIR/react-* && rm -rf node_modules/ && npm cache verify && npm install && npm start -- --reset-cache

But, what interesting, after that I tweaked tsconfig.json, Atom doesn't complain about paths like @app/support/store, it even provides autocompletion, it recognizes @app/support/ as directory and @app/support/store as a script, so I assume tsconfig.json is not the problem.

2
  • 1. I assume you restarted your packager? 2. Is that all of the error you get? 3. Does import work for anything else beside support/store, e.g. @app/constants/app? Commented Jan 11, 2020 at 22:38
  • @nabn No, the import doesn't work for any files with the absolute path. By packager you mean Metro? Then restarting it won't fix it, I tried, as well as clearing cache yarn start --reset-cache. Commented Jan 11, 2020 at 22:40

2 Answers 2

7

Seems the problem was with babel configuration. You would need to run

yarn add --dev babel-plugin-module-resolver

to install module-resolver and then adjust babel.config.js so it would look like this:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['./src'],
        alias: {
          '^@app/(.+)': './src/\\1',
        },
      },
    ],
  ],
}
Sign up to request clarification or add additional context in comments.

3 Comments

That helped, thanks! Make sure you delete the watchman cache after adding the module resolver to the babel config.
@Katherine the package name should be babel-plugin-module-resolver
Setting alias to simply { '@app': './src/app' } also worked for me.
0

In my case, I was using RePack, and I forgot to add alias in resolve.

Heres an example, Webpack and RsPack documentation for more references

export default {
  // ... RsPack config

  resolve: {
    ...Repack.getResolveOptions(),
    alias: {
      "@": path.resolve(__dirname, './src/modules'),
      "@core": path.resolve(__dirname, './src/modules/core'),
      "@customers": path.resolve(__dirname, './src/modules/customers'),
      "@notifications": path.resolve(__dirname, './src/modules/notifications'),
      "@profile": path.resolve(__dirname, './src/modules/profile'),
      "@signin": path.resolve(__dirname, './src/modules/signin')
    }
  }
}

I just noticed that paths should be the same as babel.config.js

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.