Matteo Granzotto - 28 Agosto, 2020

Create React App: importare moduli utilizzando gli alias con Webpack e Typescript

Puoi vedere il codice di questo tutorial qui, e seguire la guida, step dopo step, in questa PR.

Puoi provare la demo qui.

Inizializzare il progetto usando Create React App

Eseguire i seguenti comandi:

npx create-react-app cra-with-module-alias --template typescript
cd cra-with-module-alias

Impostare l'ambiente ed installare le dipendenze

Eseguire:

npm run eject

Rispondi yes alla domanda che ti viene proposta:

? Are you sure you want to eject? This action is permanent.

Dopo queste azioni ti ritroverai con la seguente struttura:

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

Esegui, poi, per installare le dipendenze:

npm i

Crea l'architettura delle cartelle

Creare le seguenti cartelle all'interno di src:

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

e dentro ad ognuna di queste cartelle, crea un file index.ts. In ogni file index.ts andremo ad esportare le sotto cartelle. La sintassi per gli export che andremo ad utilizzare è:

export { default as ComponentName } from "./ComponentName/ComponentName";

Aggiorna la configurazione di Webpack per utilizzare gli alias al posto dei path relativi

Aggiungi in config/webpack.config.js - in particulare nella variabile resolve.alias dell'oggetto esportato - le seguenti linee di codice:

// 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 questo modo saremo capaci di fare così all'interno di ogni componente:

import { ComponentName } from 'Components';
import { ServiceName } from 'Services';
...

Aggiorna la configurazione di Typescript per utilizzare gli alias al posto dei path relativi

Il secondo step da fare per utilizze gli alias è quello di aggiornare la connfigurazione di Typescript. Aggiungi in tsconfig.json le seguenti linee di codice:

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

in questo modo, il compilatore di Typescript sarà capace di risolvere i path.

Riorganizziamo i file

Ora andreamo a riorganizzare i file generati dal comando npm run eject.

Iniziando dalla cartella assets spostiamo logo.svg dentro una nuova cartella images. E all'interno del file index, esportriamo l'asset:

export { default as Logo } from './images/logo.svg';

Ora, per i componenti, spostiamo App.css, App.tsx e App.test.ts dentro una nuova cartella chiamata App. Dentro App/App.tsx modifichiamo la linea import logo from './logo.svg'; facendola diventare import { Logo as logo } from 'Assets';.

E dentro il file index, esportiamo:

export { default as Logo } from './images/logo.svg';

Alla fine, dovremmo aggiornare src/index.tsx come segue:

// 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();

Aggioriamo la configurazione di Jest nel package.json per eseguire i test

Per eseguire i test con i moduli come alias, dobbiamo aggiornare la consigurazione di Jest all'interno del package.json come segue:

// 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"
    },
  }
}

Tips per Visual Studio Code

Utilizzando Visual Studio Code come editor, sarà possibile ottenere i nomi dei moduli con la combinazione CTRL+Space (o la vostra combinazione).

Riferimenti

  • 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

Conslusioni

Facendo questi piccoli step porteremo un grosso beneficio all'interno del progetto facendo si che si utilizzino più i path relativi. In più, il nostro codice sarà più flessibile al cambiamento.

Puoi vedere il codice di questo tutorial qui, e seguire la guida, step dopo step, in questa PR.

Puoi provare la demo qui.

Se hai qualsiasi domanda, scrivici nella chat o via emil a 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