Create React App: import modules using aliases with Webpack and Typescript
Matteo Granzotto - Aug 28, 2020
Using Webpack and Typescript is possible to forget relative paths and to use aliases for better developer experience.
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
Setup the environment and install dependencies
Execute:
npm run eject
To the below question, answer with yes
:
? Are you sure you want to eject? This action is permanent.
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
Install the dependencies:
npm i
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";
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/'),
},
...
},
...
};
in this way we are able to do inside every component:
import { ComponentName } from 'Components';
import { ServiceName } from 'Services';
...
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"],
}
},
...
}
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';
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';
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();
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"
},
}
}
Visual Studio Code Tips
Using Visual Studio Code as editor, you can get component names via autocomplete using CTRL+Space
(or using your combinations).
Reference
- https://reactjs.org/docs/create-a-new-react-app.html
- https://create-react-app.dev/
- https://create-react-app.dev/docs/available-scripts#npm-run-eject
- https://www.typescriptlang.org/
- https://webpack.js.org/configuration/resolve/
- https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
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 on the chat or an email to info@wavelop.com.
Credits
jsconfig.json Reference - Visual Studio Code
Absolute Imports and Module path aliases
Path aliases with TypeScript in Node.js
Webpack Aliases Keep My Code Sane
Convert TypeScript tsconfig paths to webpack alias paths
Using Webpack aliases with Typescript and Jest
create-react-app Typescript 3.5, Path Alias
How to use Webpack alias with TypeScript Declaration
Aliasing with Webpack 4 and awesome-typescript loader not working
Typescript can't find modules which are imported with webpack alias
Webpack resolve.alias does not work with typescript?
Configuring aliases in webpack + VS Code + Typescript + Jest
Webpack alias in TypeScript declarations
Type-safe es2015 module import path aliasing with Webpack, Typescript and Jest
imi 10 risultati su Google per la ricerca: create react app typescript alias
create-react-app Typescript 3.5, Path Alias
How to configure react-script so that it doesn't override tsconfig.json on 'start'
absolute path with react, react-app-rewire and typescript
How to set alias path via webpack in CRA (create-react-app) and craco?
How do I configure absolute paths for imports in TypeScript based React Native apps?
Resolve imports alias path - typescript
TypeScript {paths} are not taken into consideration
create-react-app Typescript 3.5, Path Alias
Use typescript module resolve in create-react-native-app
Creating path aliases in create-react-app with react-app-rewired
Using TypeScript's absolute paths in Create React App 2.0 without ejecting
Using absolute (alias) imports in Javascript and VSCode
Add Webpack aliases to your CRA app, without pain