DEV Community

Cover image for Create React App: import modules using aliases with Webpack and Typescript
Matteo Granzotto
Matteo Granzotto

Posted on

Create React App: import modules using aliases with Webpack and Typescript

You can find the code of this tutorial here, and follow the guide, step by step, in this PR.

You can take a look at a demo here.

Initialize project using Create React App

Execute the following commands:

npx create-react-app cra-with-module-alias --template typescript
cd cra-with-module-alias
Enter fullscreen mode Exit fullscreen mode

Setup the environment and install dependencies

Execute:

npm run eject
Enter fullscreen mode Exit fullscreen mode

To the below question, answer with yes:

? Are you sure you want to eject? This action is permanent.
Enter fullscreen mode Exit fullscreen mode

You will have the following structure:

cra-with-module-alias
├── README.md
├── node_modules
├── package.json
├── package-lock.json
├── .gitignore
├── config
│   ├── webpack.config.js
│   ├── ...
│   └── Other folder and files
├── scripts
│   ├── build.js
│   ├── start.js
│   └── test.js
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
└── src
    ├── App.css
    ├── App.tsx
    ├── App.test.tsx
    ├── index.css
    ├── index.tsx
    ├── logo.svg
    ├── react-app-env.d.ts
    ├── serviceWorker.ts
    └── setupTests.ts
Enter fullscreen mode Exit fullscreen mode

Install the dependencies:

npm i
Enter fullscreen mode Exit fullscreen mode

Create the architecture folders

Create the following folders inside the src one:

  • assets;
  • components;
  • pages;
  • services.

and inside of all of these folders, create an index.ts file.
Inside of every index.ts file, we are going to export the contained subfolders. The syntax that we are going to use will be something like:

export { default as ComponentName } from "./ComponentName/ComponentName";
Enter fullscreen mode Exit fullscreen mode

Update Webpack configuration to use aliases instead of relative paths

Add to config/webpack.config.js file - in particular in the resolve.alias variables of the return object - the following lines:

// config/webpack.config.js
...
module.exports = {
    ...
    resolve: {
      ...
      alias: {
        ...
        'Assets': path.resolve(__dirname, '../src/assets/'),
        'Components': path.resolve(__dirname, '../src/components/'),
        'Pages': path.resolve(__dirname, '../src/pages/'),
        'Services': path.resolve(__dirname, '../src/services/'),
      },
      ...
    },
    ...
};
Enter fullscreen mode Exit fullscreen mode

in this way we are able to do inside every component:

import { ComponentName } from 'Components';
import { ServiceName } from 'Services';
...
Enter fullscreen mode Exit fullscreen mode

Update Typescript configuration to use aliases instead of relative paths

The second step, to use aliasing, is to update the Typescript configuration. Add to tsconfig.json file the following lines:

// tsconfig.json
{
  "compilerOptions": {
    ...
    "baseUrl": "./",
    "paths": {
      "Assets": [ "src/assets"],
      "Components": [ "src/components"],
      "Pages": [ "src/pages"],
      "Services": [ "src/services"],
    }
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

in this way, the Typescript compiler will be able to resolve paths.

Reorganize the files

Now we are going to re-organize the file generated by the npm run eject command.

Starting from the assets folder, we move logo.svg inside a new images folder. And inside the index file, we export the file:

export { default as Logo } from './images/logo.svg';
Enter fullscreen mode Exit fullscreen mode

Now, for components, we move the App.css, App.tsx and App.test.ts inside a new folder called App.
Inside App/App.tsx file we update the import line import logo from './logo.svg'; in import { Logo as logo } from 'Assets';.

And inside the index file, we export the file:

export { default as Logo } from './images/logo.svg';
Enter fullscreen mode Exit fullscreen mode

In the end, we need to update src/index.tsx as the following:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { App } from 'Components'; // <-- New way to import Components
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Enter fullscreen mode Exit fullscreen mode

Update config in package.json for running test via Jest

To execute the test with modules as aliases, we need to update the jest configuration in package.json as follow:

// package.json
{
  ...
  "jest": {
    ...
    "moduleDirectories": [
      ".",
      "src",
      "node_modules"
    ],
    "moduleNameMapper": {
      ...
      "^Assets(.*)$": "<rootDir>/src/assets/$1",
      "^Components(.*)$": "<rootDir>/src/components/$1",
      "^Pages(.*)$": "<rootDir>/src/pages/$1",
      "^Services(.*)$": "<rootDir>/src/services/$1"
    },
  }
}
Enter fullscreen mode Exit fullscreen mode

Visual Studio Code Tips

Using Visual Studio Code as editor, you can get component names via autocomplete using CTRL+Space (or using your combinations).

Visual Studio Code

Reference

Conclusion

Doing these simple steps you will be able to forget the relative paths and make your folders structure more flexible to the changes.

You can find the code of this tutorial here, and follow the guide, step by step, in this PR.

You can take a look at a demo here.

If you have questions, please write to us an email to info@wavelop.com.

Originally published at https://wavelop.com/en/story/create-react-app-module-import-path-aliasing-with-webpack-typescript/ on August 28, 2020.

Credits

Top comments (1)

Collapse
 
segersalex profile image
Alex Segers • Edited

If you're wondering how enable importing nested files with your aliases, duplicate each alias under "paths" in your tsconfig.json and add "/*" to both its name and path. No additional configuration to webpack.config.js is necessary.