Тестирование с использованием псевдонимов Jest и Webpack

Я ищу возможность использовать псевдонимы веб-пакетов для разрешения импорта при использовании jest и оптимально webpack.aliases чтобы избежать дублирования.

Jest conf:

  "jest": {
    "modulePaths": ["src"],
    "moduleDirectories": ["node_modules"],
    "moduleNameMapper": {
      "^@shared$": "<rootDir>/shared/",
      "^@components$": "<rootDir>/shared/components/"
    }
  },

Псевдонимы веб-пакетов:

exports.aliases = {
    '@shared': path.resolve(paths.APP_DIR, 'shared'),
    '@components': path.resolve(paths.APP_DIR, 'shared/components'),
};

Импорт:

import Ordinal from '@shared/utils/Ordinal.jsx';
import Avatar from '@components/common/Avatar.jsx';

По какой-то причине @ вызывает проблемы, поэтому при удалении (как псевдоним и импорт), он может найти shared но components все еще не может быть решена.

 FAIL  src/shared/components/test/Test.spec.jsx
  ● Test suite failed to run

    Cannot find module '@shared/utils/Ordinal.jsx' from 'Test.jsx'

Я попытался использовать jest-webpack-alias, https://github.com/tleunen/babel-plugin-module-resolver и документы Jest/Webpack.

9 ответов

Решение

Кажется, это было исправлено.

Ниже приведена рабочая настройка:

Версии

"jest": "~20.0.4"

"webpack": "^3.5.6"

package.json

"jest": {
  "moduleNameMapper": {
    "^@root(.*)$": "<rootDir>/src$1",
    "^@components(.*)$": "<rootDir>/src/components$1",
  } 
}

webpack.shared.js

const paths = {
  APP_DIR: path.resolve(__dirname, '..', 'src'),
};

exports.resolveRoot = [paths.APP_DIR, 'node_modules'];

exports.aliases = {
  '@root': path.resolve(paths.APP_DIR, ''),
  '@components': path.resolve(paths.APP_DIR, 'components'),
};

Так как у меня была та же проблема, прежде чем я снова прочитал, и на этот раз более тщательно документацию. Правильный конфиг должен быть:

  "jest": {
    "moduleNameMapper": {
      "^@shared(.*)$": "<rootDir>/shared$1",
      "^@components(.*)$": "<rootDir>/shared/components$1"
    }
  },

Для всех, кто использует в качестве root их модулей, вы должны быть более конкретными, поскольку другие библиотеки могут использовать @ в узловых модулях.

        moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1"
  },

Это переводится как «все, что соответствует @/ должен быть отправлен <rootDir>/src/<rest of the path>

С использованием: "jest": "^26.5.3", а также "webpack": "4.41.5", Мне удалось правильно сопоставить псевдонимы webpack / typescript в jest.config.js с этим шаблоном:

Конфигурация Webpack:

      module.exports = {
   // the rest of your config
    resolve: {
      alias: {
        'components': path.resolve(__dirname, 'js/app/components'),
        'modules': path.resolve(__dirname, 'js/app/modules'),
        'types': path.resolve(__dirname, 'js/types'),
        'hooks': path.resolve(__dirname, 'js/app/hooks'),
        'reducers': path.resolve(__dirname, 'js/app/reducers'),
        '__test-utils__': path.resolve(__dirname, 'js/app/__test-utils__') 
      }
    },
}

Jest.config.js:

        moduleNameMapper: {
    '^types/(.*)$':  '<rootDir>/js/types/$1',
    '^components/(.*)$': '<rootDir>/js/app/components/$1',
    '^modules/(.*)$':  '<rootDir>/js/app/modules/$1',
    '^hooks/(.*)$':  '<rootDir>/js/app/hooks/$1',
    '^reducers/(.*)$':  '<rootDir>/js/app/reducers/$1',
    '^__test-utils__/(.)$': '<rootDir>/js/app/__test-utils__/$1' 
  }

Вот объяснение символов:

  • (.*)$: захватить все, что идет после точного совпадения (каталог)
  • $1: сопоставьте его с этим значением в указанном мной каталоге.

и tsconfig.json:

          "paths": {
      "config": ["config/dev", "config/production"],
      "components/*": ["js/app/components/*"],
      "modules/*": ["js/app/modules/*"],
      "types/*": ["js/types/*"],
      "hooks/*": ["js/app/hooks/*"],
      "reducers/*": ["js/app/reducers/*"],
      "__test-utils__/*": ["js/app/__test-utils__/*"]
    }

FWIW, попробуйте переключить порядок псевдонимов, держите более конкретный вверх и менее конкретный вниз, например

"moduleNameMapper": {
  "^@components$": "<rootDir>/shared/components/",
  "^@shared$": "<rootDir>/shared/"
}

Ни один из предложенных ответов у меня не помог.

Смог решить по следующей схеме:

Jest версии 25+

moduleNameMapper: {
    '^Screens(.*)': '<rootDir>/src/screens/$1',
    '^Components(.*)': '<rootDir>/src/components/$1',
    '^Assets(.*)': '<rootDir>/src/assets/$1',
    '^Services/(.*)': '<rootDir>/src/services/$1',
  },

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

"jest": {
  "moduleNameMapper": {
    '@root/(.*)': '<rootDir>/../$1'
  }
}

Не работает.

Но когда я делаю то же самое в jest.config.js оно работает:

module.exports = {
   moduleNameMapper: {
     '@root/(.*)': '<rootDir>/../$1'
   }
}

Это решение хорошо работает для меня:

moduleNameMapper: {
    '^Screens(.*)': '<rootDir>/src/screens/$1',
    '^Components(.*)': '<rootDir>/src/components/$1',
    '^Assets(.*)': '<rootDir>/src/assets/$1',
    '^Services/(.*)': '<rootDir>/src/services/$1',
  },

Предположим, что ваши псевдонимы webpack лежат в webpack.yml в блоке «resolved_paths».

Чтобы добавить такие же псевдонимы в jest, если ваша конфигурация jest находится в package.json:

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