使用 Jest 和 Webpack 别名进行测试

Testing with Jest and Webpack aliases

我希望能够在使用 jest 时使用 webpack 别名来解析导入,并且最好参考 webpack.aliases 以避免重复。

开玩笑会议:

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

Webpack 别名:

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';

由于某种原因,@ 会导致问题,因此当删除时(在别名和导入中),它可以找到 sharedcomponents 仍然无法解决。

 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, babel-plugin-module-resolver and the Jest/Webpack docs

FWIW,尝试切换别名顺序,保持更具体的在上,不太具体的在下,例如

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

因为我之前也遇到过同样的问题,所以再看一遍,这次更仔细的看文档。正确的配置应该是:

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

这似乎已经修复。

下面是一个工作设置:

版本

"jest": "~20.0.4"

"webpack": "^3.5.6"

package.json

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

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'),
};

None 的指定答案对我有用。

能够使用以下模式解决:

Jest 版本 25+

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

这个解决方案很适合我:

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

这真是太疯狂了,但是当我尝试像这样在 package.json 中映射模块时:

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

没用。

但是当我在 jest.config.js 中做同样的事情时,它起作用了:

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

使用:"jest": "^26.5.3","webpack": "4.41.5", 我能够将 jest.config.js 中的 webpack/typescript 别名与此模式正确匹配:

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/',
    '^components/(.*)$': '<rootDir>/js/app/components/',
    '^modules/(.*)$':  '<rootDir>/js/app/modules/',
    '^hooks/(.*)$':  '<rootDir>/js/app/hooks/',
    '^reducers/(.*)$':  '<rootDir>/js/app/reducers/',
    '^__test-utils__/(.)$': '<rootDir>/js/app/__test-utils__/' 
  }

符号的解释如下:

  • (.*)$: 捕获完全匹配后的任何内容(目录)
  • </code>:映射到我指定目录下的这个值。</li> </ul> <p>和tsconfig.json:</p> <pre><code> "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__/*"] }

对于使用 @ 作为其模块的 root 的任何人,您必须更加具体,因为其他库可以在节点模块中使用 @

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

它翻译成“任何匹配@/的东西都应该发送到<rootDir>/src/<rest of the path>

假设您的 webpack 别名位于“resolved_paths”块中的 webpack.yml。

要在 jest 中添加相同的别名,如果您的 jest 配置在 package.json:

"jest":{
  "moduleDirectories":{
     ".",
      "<rootDir>/shared/components/",
      "<rootDir>/shared/",
      "node_modules"
  }
}