- Create React App: import modules using aliases with Webpack and Typescript
- Initialize project using Create React App
- Setup the environment and install dependencies
- Create the architecture folders
- Update Webpack configuration to use aliases instead of relative paths
- Update Typescript configuration to use aliases instead of relative paths
- Reorganize the files
- Update config in package.json for running test via Jest
- Visual Studio Code Tips
- Reference
- Conclusion
- Credits
- What is a path alias?
- Starter Project
- Note about the path alias resolution options
- How to resolve Javascript path alias with module-alias
- Install the module-alias packge
- Configure package.json
- Import the module in index.ts
- Build the project again
- Start the Javascript Project
- How to resolve a Typescript path alias with ts-node
- Install the tsconfig-paths module
- run ts-node with tsconfig-paths
- How to resolve path alias with ts-node and Nodemon
- Install the packages
- configure nodemon
- add a script for development
- run the code
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
Setup the environment and install dependencies
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
Create the architecture folders
Create the following folders inside the src one:
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'; // 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(.*)$": "/src/assets/$1", "^Components(.*)$": "/src/components/$1", "^Pages(.*)$": "/src/pages/$1", "^Services(.*)$": "/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
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 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
What is a path alias?
Path alias is a way to define an absolute path in your typescript project with a word, path or a character.
a very common syntax you will see is replacing the src directory with @
The advantage of using a path alias is that you no longer need to use a lot of directory traversals in your imports.
import < userRouter >from '../../routers/userRouter'
import < userRouter >from '@/routers/userRouter'
The beauty of this solution is that you no longer need to do long path traversals to import your packages, and it doesn’t matter where your file is, as the import statement will always be the same.
I have also covered how to configure path alias for react and storybook, you can check them out here:
How to configure path alias in react
How to configure path alias in storybook
Starter Project
So let us start with a sample mock project. You can go ahead with the starter repository that we have here:
so we’ll change usersRouter.ts to this:
import express from 'express'; import < getUsers >from '@/controllers/usersController'; export const usersRouter = express.Router(); usersRouter.get('/', getUsers);
import express from 'express'; import < createTask, deleteTask, getSingleTask, getTasks, updateTask, >from '@/controllers/tasksController'; export const tasksRouter = express.Router(); tasksRouter.get('/', getTasks); tasksRouter.get('/:taskId', getSingleTask); tasksRouter.get('/', createTask); tasksRouter.get('/:taskId', updateTask); tasksRouter.get('/:taskId', deleteTask);
Now if we attempt to build our project, Typescript won’t be giving us any errors.
we can build the project with this command:
yarn build # this runs -> tsc
This will generate our compiled project in javascript, and it will be in the dist folder.
if we attempt to run the compiled code with this command:
yarn start # this runs -> node dist/index.js
internal/modules/cjs/loader.js:892 throw err; ^ Error: Cannot find module '@/controllers/usersController' . code: 'MODULE_NOT_FOUND', .
This is happening because the tsconfig.json we have only applies to our typescript code. Node is not aware of this configuration when it comes to the compiled Javascript code. So we will need to configure it so it cna understand the path alias that we configured.
Note about the path alias resolution options
for each of the provided options, they assume that you are continuining from the “How to configure Typescript Path Alias” section, and they do not build on top of each other.
How to resolve Javascript path alias with module-alias
There are various ways to do this, but the easiest thing we can do is by using a package called module-alias. This solution is specific to resolving the path aliases found in the compiled Javascript code
Install the module-alias packge
Configure package.json
We will need a property to our package.json, called _moduleAliases
in there, we will let i know what our alias configuration is, but we want it to know to resolve it for the javascript compiled code.
this means that we will have to point to dist rather than src , as our javascript code is going to import the modules from there.
also notice that we did not add the trailing / after the @ in our configuration.
Import the module in index.ts
finally we’ll import the module itself, this will be in our typescript app’s entry file, typically /src/index.ts .
We will add this line at the top of the file, before any import.
import 'module-alias/register'; // 👈 add this one import express from 'express'; import < valdiateAdminRole >from './middlewares/validateAdminRole'; import < validateToken >from './middlewares/validateToken'; import < usersRouter >from './routes/admin/usersRouter'; import < tasksRouter >from './routes/tasksRouter'; const app = express(); app.use('/api/tasks', validateToken, tasksRouter); app.use('/api/admin/users', validateToken, valdiateAdminRole, usersRouter); app.listen(5000, () => < console.log('server started at port 5000!'); >);
Build the project again
yarn build # this runs -> tsc
Start the Javascript Project
yarn start # this runs -> node dist/index.js
The project will start without issues here!
How to resolve a Typescript path alias with ts-node
With ts-node, the same steps we did for node configuration that are in the previous section will work as well.
Tough there is another way to do it, which is through the package tsconfig-paths.
Once again, if we attempt to run the app with ts-node , we will get this error:
$ ts-node src/index.ts Error: Cannot find module '@/controllers/usersController' Require stack:
so to configure the resolution part, we will:
Install the tsconfig-paths module
yarn add -D ts-node tsconfig-paths
run ts-node with tsconfig-paths
if you have ts-node installed globally:
ts-node -r tsconfig-paths/register src/index.ts
if you have ts-node installed for just this project:
yarn ts-node -r tsconfig-paths/register src/index.ts
so the important part is we register the resolver package through the argument -r tsconfig-paths/register
for neat-ness sake, we can add this as a script in our package.json file like so:
"version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": < "dev": "ts-node -r tsconfig-paths/register src/index.ts", "build": "tsc", "start": "node dist/index.js" >, .
and then we can just run our code like so:
How to resolve path alias with ts-node and Nodemon
This approach might be the most comfortable one to have during development. It resolves the path alias, runs the code, and reloads it when the code is updated.
Install the packages
yarn add -D nodemon ts-node tsconfig-paths
configure nodemon
At the root directory of our repository, we’ll create a nodemon.json file.
in that file, we’ll add the following:
ignore is set to ignore the files we do not want to watch. this would be the unit testing files, git and node moduels.
watch mark our src directory as the one to watch for any of its changes. If a change is detected there, then it will re-run the exec command.
exec contains the command that we want to run whenever a file that we are tracking in watch changes.
ext filters the type of files we want to watch for.
add a script for development
in package.json , we’ll simply add this line under scripts :
run the code
and from this point on, our code runs while it understands the path alias, and it reloads when we update our code!
Sing up to get an email notification when new content is published