Setting Up Absolute Paths in React TypeScript Project ===================================================== This guide provides a comprehensive walkthrough for setting up absolute paths in a React TypeScript project using Vite and Vitest, including necessary adjustments to ESLint and TypeScript configurations. Prerequisites ------------- - Node.js (version 14 or later recommended) - A React TypeScript project set up with Vite - Vitest for testing - ESLint for linting Step 1: Update tsconfig.json ---------------------------- Update your ``tsconfig.json`` to include path aliases and necessary types: .. code-block:: json { "compilerOptions": { // ... other options ... /* Absolute Imports */ "baseUrl": ".", "paths": { "@/*": ["src/*"] }, /* Types */ "types": ["vitest/globals", "node"] }, "include": ["src", "*.config.ts"] } The ``"types"`` array includes: - ``"vitest/globals"`` for Vitest testing types - ``"node"`` for Node.js types, which are often needed in config files and for certain Vite/Vitest functionalities Step 2: Create or Update tsconfig.node.json ------------------------------------------- Create or update ``tsconfig.node.json`` to include configuration files: .. code-block:: json { "compilerOptions": { "composite": true, "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts", "vitest.config.ts"] } Including ``"vitest.config.ts"`` here ensures that TypeScript processes this config file correctly, which is crucial for ESLint and TypeScript to work together smoothly on configuration files. Step 3: Install vite-tsconfig-paths ----------------------------------- Install ``vite-tsconfig-paths`` as a dev dependency: .. code-block:: bash npm install -D vite-tsconfig-paths # or yarn add -D vite-tsconfig-paths Step 4: Update vite.config.ts ----------------------------- Modify your ``vite.config.ts`` to use the ``vite-tsconfig-paths`` plugin: .. code-block:: typescript import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react-swc'; import tsconfigPaths from 'vite-tsconfig-paths' export default defineConfig({ plugins: [react(), tsconfigPaths()], }); The ``tsconfigPaths()`` plugin allows Vite to resolve imports according to the ``paths`` configuration in your ``tsconfig.json``. Step 5: Update vitest.config.ts ------------------------------- Update your ``vitest.config.ts`` to include the ``tsconfigPaths`` plugin and use the correct types: .. code-block:: typescript import { defineConfig, UserConfigExport } from 'vitest/config'; import tsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig({ plugins: [tsconfigPaths()], test: { environment: 'jsdom', globals: true, setupFiles: './src/setupTests.ts', coverage: { provider: 'v8', reporter: ['text', 'json', 'html'], include: ['src/**/*.{js,jsx,ts,tsx}'], exclude: [ 'src/**/*.{test,spec}.{js,jsx,ts,tsx}', 'src/setupTests.ts', 'src/vite-env.d.ts', ], }, }, } as UserConfigExport); The ``as UserConfigExport`` type assertion ensures type compatibility with Vitest's configuration, resolving potential type conflicts between Vite and Vitest configurations. Step 6: Update ESLint Configuration ----------------------------------- Update your ESLint configuration (``eslint.config.js`` or ``.eslintrc.js``) to handle absolute imports and config files: .. code-block:: javascript import { fixupPluginRules } from '@eslint/compat'; import typescript from '@typescript-eslint/eslint-plugin'; import typescriptParser from '@typescript-eslint/parser'; export default [ // ... other configurations ... { files: ['src/**/*.{ts,tsx}'], // ... other settings ... rules: { // ... other rules ... 'import/order': [ 'error', { groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], 'newlines-between': 'always', pathGroups: [ { pattern: '@/**', group: 'internal', }, ], alphabetize: { order: 'asc', caseInsensitive: true }, }, ], }, }, { files: ['*.config.ts', 'vite.config.ts', 'vitest.config.ts'], languageOptions: { parser: typescriptParser, parserOptions: { ecmaVersion: 'latest', sourceType: 'module', project: './tsconfig.node.json', }, }, plugins: { '@typescript-eslint': fixupPluginRules(typescript), }, rules: { ...typescript.configs.recommended.rules, 'import/no-extraneous-dependencies': 'off', '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-var-requires': 'off', '@typescript-eslint/ban-ts-comment': 'off', }, }, ]; These ESLint configurations: - Handle absolute imports with the ``@/`` prefix - Apply specific rules to configuration files to avoid common linting issues in Vite and Vitest configs Usage ----- After setting up, you can use absolute imports in your code: .. code-block:: typescript // Instead of import { SomeComponent } from '../../../components/SomeComponent'; // You can now use import { SomeComponent } from '@/components/SomeComponent'; This works in both your source files and test files. Step 7: Adding Custom Absolute Paths ------------------------------------ You can create additional custom absolute paths for specific directories like ``components`` and ``utils``. This can make your imports even more concise and organized. 1. Update your ``tsconfig.json``: .. code-block:: json { "compilerOptions": { // ... other options ... "baseUrl": ".", "paths": { "@/*": ["src/*"], "@components/*": ["src/components/*"], "@utils/*": ["src/utils/*"] } } } 2. Update your ``vite.config.ts``: The ``vite-tsconfig-paths`` plugin will automatically read these new paths, so no changes are needed in the Vite configuration. 3. Update your ESLint configuration: Add the new path patterns to your ESLint configuration to ensure proper linting: .. code-block:: javascript { // ... other configurations ... rules: { 'import/order': [ 'error', { groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], 'newlines-between': 'always', pathGroups: [ { pattern: '@/**', group: 'internal', }, { pattern: '@components/**', group: 'internal', }, { pattern: '@utils/**', group: 'internal', }, ], alphabetize: { order: 'asc', caseInsensitive: true }, }, ], }, } Usage with Custom Paths ^^^^^^^^^^^^^^^^^^^^^^^ Now you can use these custom paths in your imports: .. code-block:: typescript // Instead of import { Button } from '../../../components/Button'; import { formatDate } from '../../../utils/dateUtils'; // You can now use import { Button } from '@components/Button'; import { formatDate } from '@utils/dateUtils'; This approach allows for even more concise and intuitive imports, especially in larger projects with deep directory structures. Troubleshooting --------------- If you encounter issues: 1. Ensure all configuration files are up to date. 2. Restart your development server and any running ESLint or TypeScript processes. 3. If using VS Code, reload the window or restart the TypeScript server. 4. Check that all necessary dependencies are installed, including ``@types/node`` if you're using Node.js types.