Как установить путь псевдонима через веб-пакет в CRA (create-реагировать-приложение) и Craco?

У меня проблема с заданным псевдонимом в веб-пакете с использованием create-реагировать-app и craco, я уже погуглил его, но не могу решить проблему. Я получил ошибку Module not found: Can't resolve '@app/App' in 'C:\ReactSandbox\my-project\src каждый раз, когда я запускаю приложение с помощью команды yarn start

Действия по воспроизведению:

  1. create-react-app my-project
  2. cd my-project
  3. yarn add @craco/craco
  4. cat > craco.config.js (см. конфигурацию ниже)
  5. замещать react-scripts в craco в разделе "script" на package.json (запуск craco, сборка craco и т. д.)
  6. редактировать файл src/index.js (заменить строку 4, см. код ниже)
  7. yarn start

craco.config.js

const path = require("path");

module.exports = {
  webpack: {
    resolve: { 
      alias: {
        "@app": path.resolve(__dirname, "src/"),
      }
    }    
  }
};

SRC /index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from '@app/App'; //replace './App' into '@app/App'
import * as serviceWorker from './serviceWorker';

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

serviceWorker.unregister();

Текущий результат

Module not found: Can't resolve '@app/App' in 'C:\ReactSandbox\my-project\src

ожидаемый

Я избегаю вызова относительного пути ада, а не модуля импорта, как ../../../../FilterComment.jsбыло бы чисто написать @app/FilterComment.js

8 ответов

решение для карко:

Вам нужно установить craco-alias, тогда напишите в craco.config.js

          const CracoAlias = require('craco-alias')

    module.exports = {
      plugins: [
        {
          plugin: CracoAlias,
          options: {
            source: 'tsconfig',
            baseUrl: '.',
            tsConfigPath: './tsconfig.path.json',
          },
        },
      ],
    }

tsconfig.path.json

          {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"],
          "@svg/*": ["src/assets/svg/*"],
          "@img/*": ["src/assets/images/*"],
          "@icons/*": ["src/assets/icons/*"],
          "@shared/*": ["src/shared/*"],
          "@components/*": ["src/components/*"],
          "@hooks/*": ["src/hooks/*"],
          "@constants/*": ["src/constants/*"],
          "@layout/*": ["src/layout/*"],
          "@services/*": ["src/services/*"]
        }
      }
    }

tsconfig.json

          {
      "extends": "./tsconfig.path.json",
      "compilerOptions": {
        "target": "es5",
        "lib": [
          "dom",
          "dom.iterable",
          "esnext"
        ],
        "allowJs": true,
        "checkJs": false,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "declaration": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react-jsx",
        "noFallthroughCasesInSwitch": true,
        "removeComments": true
      },
      "include": [
        "src",
        "src/configs",
        "react-app-env.d.ts"
      ]
    }

Нам нужно 2 шага, чтобы добавить псевдонимы

  1. сообщить IDE о псевдонимах в tsconfig.json
  2. сообщить webpack о псевдонимах

Первый:

создайте отдельный файл tsconfig.path.json и добавьте псевдонимы:

{
   "compilerOptions": {
      "baseUrl": "./src",
      "paths": {
         "@utils/*": ["utils/*"]
      }
   }
}

Добавить создано tsconfig.path.json к главному tsconfig.json

{
   "extends": "./tsconfig.paths.json",
   ... other staff ...
}

Второй:

Добавить псевдонимы к config-overrides.js

const {
   override,
   addWebpackAlias
} = require('customize-cra');

const path = require("path");

module.exports = override(
   addWebpackAlias({
      "@utils": path.resolve(__dirname, "./src/utils"),
   }),
);

У меня работает, удачного кодирования;)

Мой craco.config.js выглядит так, как показано ниже, он работает:

const path = require('path');enter code here

module.exports = {
    // ...
    webpack: {
        alias: {
            '@': path.join(path.resolve(__dirname, './src')),
        }
    }
}

Просто держи свой файл craco.config.js просто так, и вам нужно добавить еще 1 файл с именем jsconfig.json

это содержание:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2016",
    "jsx": "preserve",
    "checkJs": true,
    "baseUrl": "./src/",
    "paths": {
      "@app/*": ["./*"]
    }
  },
  "exclude": ["node_modules", "**/node_modules/*"]
}

тогда вы можете импортировать из абсолютного пути, как @app/FilterComment.js

Это также работает для VSCode (редактор теперь понимает, где @app указать на). Но если вы хотите, чтобы VSCode выполнял импорт автоматически, вам следует добавить дополнительные настройки, чтобы он всегда выполнял импорт по абсолютному пути.

файл .vscode/settings.jsonсодержание:

{
  "javascript.preferences.importModuleSpecifier": "non-relative"
}

Пример (который я использую) без использования зависимости:

      //craco.config.js
const path = require('path')

const tsconfig = require('./tsconfig.base.json')

const removeAsterisk = path => path.replace('/*', '')

const aliasProps = Object.entries(tsconfig.compilerOptions.paths).map(([key, value]) => {
  const newKey = removeAsterisk(key)
  let newValue = removeAsterisk(value[0])
  newValue = path.resolve(__dirname, newValue)
  return [newKey, newValue]
})

const alias = Object.fromEntries(aliasProps)

module.exports = {
  webpack: {
    alias,
  },
}

      //tsconfig.base.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["./src/*"],
      //...
    }
  }
}

      // tsconfig.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {/*...*/}
}

Рассмотрите возможность использования rewire с псевдонимом. Итак, устанавливайте и настраивайте так:

// config-overrides.js:

const {alias} = require('react-app-rewire-alias')

module.exports = function override(config) {
  alias({
    "@app": "src",
  })(config)
  return config
}

или используйте jsconfig.json или tsconfig.json сconfigPaths()

Теперь вы можете импортировать:

   import App from '@app/App'

Возможно, у OP была другая версия React / Webpack (я использую текущие версии), но поставив alias объект прямо внутри webpack объект (не вкладывая его в resolve объект) помогли мне:

      const path = require("path");

module.exports = {
  webpack: {
    alias: {
      "@app": path.resolve(__dirname, "src"),
    }
  }
};

Я использую плагин craco-alias для автоматической генерации псевдонимов для Webpack и Jest. (Я всего лишь стажер, но именно так старшие разработчики в моей компании используют абсолютный импорт в ответ)

Установить

      yarn add @craco/craco
yarn add craco-alias

craco.config.js

      const CracoAlias = require('craco-alias');

module.exports = {
  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: 'tsconfig',
        baseUrl: './src',
        tsConfigPath: './tsconfig.paths.json', // or wherever you have defined your paths
      },
    },
  ],
};

И убедитесь, что ваши скрипты в package.json выглядят следующим образом

      "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject",
    ...
  },

Тогда он будет работать, как указано в tsconfig.json.

К вашему сведению, у меня есть, "react-scripts": "4.0.3" "@craco/craco": "^6.3.0" "craco-alias": "^3.0.1"

Другие вопросы по тегам