jest.config.js 中的 `moduleNameMapper` 设置在 CircleCI 上不起作用

Posted

技术标签:

【中文标题】jest.config.js 中的 `moduleNameMapper` 设置在 CircleCI 上不起作用【英文标题】:`moduleNameMapper` settings in jest.config.js doesn't work on CircleCI 【发布时间】:2019-08-24 14:41:46 【问题描述】:

我已经在 typescript 中使用我的 React-app 进行了测试,使用 ts-jest 如下所示。

import * as React from "react";
import * as renderer from "react-test-renderer";

import  ChartTitle  from "Components/chart_title";

describe("Component: ChartTitle", () => 
  it("will be rendered with no error", () => 
    const chartTitle = "My Chart 1";
    renderer.create(<ChartTitle title=chartTitle />);
  );
);

它已经在我的本地环境中通过,但在 CircleCI 中失败了。

 FAIL  __tests__/components/chart_title.tsx
  ● Test suite failed to run

    TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
    __tests__/components/chart_title.tsx:4:28 - error TS2307: Cannot find module 'Components/chart_title'.

    4 import  ChartTitle  from "Components/chart_title";                              
                                 ~~~~~~~~~~~~~~~~~~~~~~~~

这个Components/moduleNameMapper 的别名表达式,我认为它仅在CircleCI 中不起作用。

jest --showConfig 选项告诉我本地环境和 CI 环境之间没有区别。

我的设置有问题吗?

app/frontend/jest.config.js

module.exports = 
  globals: 
    "ts-jest": 
      tsConfig: "tsconfig.json",
      diagnostics: true
    ,
    NODE_ENV: "test"
  ,
  moduleNameMapper: 
    "^Components/(.+)$": "<rootDir>/src/components/$1"
  ,
  moduleDirectories: ["node_modules", 'src'],
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
  transform: 
    "^.+\\.tsx?$": "ts-jest"
  ,
  verbose: true
;

app/frontend/tsconfig.json


  "compilerOptions": 
    "baseUrl": "src",
    "outDir": "dist",
    "allowJs": true,
    "checkJs": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "noImplicitAny": true,
    "target": "esnext",
    "module": "commonjs",
    "lib": ["es6", "dom"],
    "jsx": "react",
    "strict": false,
    "removeComments": true,
    "types": ["jest"]
  ,
  "typeRoots": ["node_modules/@types"],
  "paths": 
    "Components/*": ["src/components/*"]
  ,
  "include": ["src/**/*"],
  "exclude": ["node_modules", "__tests__"]

app/frontend/package.json


  "scripts": 
    "build": "webpack --mode development --watch",
    "build-production": "node_modules/.bin/webpack --mode production",
    "test": "jest",
    "lint": "npx eslint src/**/* __tests__/**/* --ext \".ts, .tsx\"",
  ,

app/.circleci/.config.yml

version: 2
jobs:
  build:
    ...
    steps:
      - run:
        name: run tests for frontend
        command: npm test -- -u
        working_directory: frontend

【问题讨论】:

【参考方案1】:

tsconfig-paths-jest 在 Jest >23 中不可用。对于当前的 Jest 26,我通过以下方式运行它:https://kulshekhar.github.io/ts-jest/user/config/#paths-mapping

jest.config.js

const  pathsToModuleNameMapper  = require('ts-jest/utils');
const  compilerOptions  = require('./tsconfig');

module.exports = 
  preset: 'ts-jest',
  testEnvironment: 'node',
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths,  prefix: '<rootDir>/src/'  )
;

tsconfig.json"compilerOptions"

 "baseUrl": "./src",
 "paths":             
  "@models/*": [ "./models/*" ],
  "@inputs/*": [ "./inputs/*" ],
  "@tests/*": [ "./__tests__/*" ],
  "@resolvers/*": [ "./resolvers/*" ],
  "@seeds/*": [ "./seeds/*" ],
  "@index": [ "./index.ts" ],
  "@ormconfig":[ "../ormconfig.ts" ]
  ,

【讨论】:

谢谢!这应该是正确的答案! 结合互联网,这是我找到的最好的解决方案之一。干得好,谢谢 我自己错过了 prefix: '&lt;rootDir&gt;/src/' 部分。谢谢!【参考方案2】:

我终于找到了解决办法。

根据this issue,我使用tsconfig-pathstsconfig-paths-jest

所以我的设置文件已经改变如下。

tsconfig.json


  "compilerOptions": 
    "baseUrl": ".",
    "outDir": "dist/",
    "allowJs": true,
    "checkJs": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "noImplicitAny": true,
    "target": "es6",
    "module": "commonjs",
    "lib": ["es5", "es6", "dom"],
    "jsx": "react",
    "strict": false,
    "removeComments": true,
    "types": ["node", "jest"],
    "paths": 
      "Components/*": ["src/components/*"]
    
  ,
  "typeRoots": ["node_modules/@types"],
  "include": ["src/**/*"],
  "exclude": ["node_modules", "__tests__"]

jest.config.js

/* eslint-disable import/order */
/* eslint-disable @typescript-eslint/no-var-requires */
const tsconfig = require("./tsconfig.json");
const moduleNameMapper = require("tsconfig-paths-jest")(tsconfig);

module.exports = 
  globals: 
    "ts-jest": 
      tsConfig: "tsconfig.json",
      diagnostics: true
    ,
    NODE_ENV: "test"
  ,
  setupFilesAfterEnv: [`$__dirname/src/setupTests.ts`],
  moduleDirectories: ["node_modules", 'src'],
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
  transform: 
    "^.+\\.tsx?$": "ts-jest"
  ,
  verbose: true,
  moduleNameMapper
;

而且我的测试在 CircleCI 中运行良好,但我仍然不知道为什么这些测试 在此解决方案之前曾在我当地工作过。

【讨论】:

以上是关于jest.config.js 中的 `moduleNameMapper` 设置在 CircleCI 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用不同的jest.config.js进行单元和组件测试?

如果 jest.config.js 在子文件夹或子目录中,则 Jest 需要更多时间

Jest 测试在 tsx 语法上失败

如何仅通过一个 Jest 配置文件/设置使用多个 Jest 预设?

单元测试jest部署

jest在已有项目中的安装与使用