CRA + Yarn 2 + jsconfig.json = 不能 运行 单元测试

CRA + Yarn 2 + jsconfig.json = Can't run unit tests

我的 jsconfig.json 文件中有以下配置:

{
  "compilerOptions": {
    "baseUrl": "./src"
  },
  "include": ["src"]
}

这让我可以这样做:

import { App } from 'components'
import * as actions from 'actions/app.actions'

而不是这个:

import { App } from '../components'
import * as actions from '../actions/app.actions'

为了开始单元测试,我在 src/components/tests

中创建了一个简单的 App.test.jsx
import { render } from '@testing-library/react'
import { App } from 'components'

it('renders without crashing', () => {
  render(<App />)
})

但是,当我 运行 yarn test(这是 react-scripts test 的糖)时,它会抛出这个丑陋的错误:

 FAIL  src/components/tests/App.test.jsx
  ● Test suite failed to run

    Your application tried to access components, but it isn't declared in your dependencies; 
this makes the require call ambiguous and unsound.

    Required package: components (via "components")
    Required by: C:\Users\Summer\Code\sandbox\src\components\tests\

      23714 |     enumerable: false
      23715 |   };
    > 23716 |   return Object.defineProperties(new Error(message), {
            |                                  ^
      23717 |     code: { ...propertySpec,
      23718 |       value: code
      23719 |     },

      at internalTools_makeError (.pnp.js:23716:34)
      at resolveToUnqualified (.pnp.js:24670:23)
      at resolveRequest (.pnp.js:24768:29)
      at Object.resolveRequest (.pnp.js:24846:26)

Jest(或 Yarn?)似乎认为 components 是一个节点包,因为它不知道我的 jsconfig.json 中的绝对导入设置。有没有办法让它知道?还是我必须在 0% 覆盖率和相对进口率之间做出选择?

我试过在我的 package.json 中的 "jest" 下输入 "moduleNameMapper",就像文档中解释的那样,但没有帮助。我得到了同样的错误 + 一个错误。

我也试过将测试文件中的 components 更改为 ../components 但随后它抱怨 actions/app.actions 位于 <App /> 组件中。

模块名称映射器配置:

/* package.json */
{
  /* ... */
  "jest": {
    "moduleNameMapper": {
      "actions(.*)$": "<rootDir>/src/actions",
      "assets(.*)$": "<rootDir>/src/assets",
      "components(.*)$": "<rootDir>/src/components",
      "mocks(.*)$": "<rootDir>/src/mocks",
      "pages(.*)$": "<rootDir>/src/pages",
      "reducers(.*)$": "<rootDir>/src/reducers",
      "scss(.*)$": "<rootDir>/src/scss",
      "store(.*)$": "<rootDir>/src/store",
      "themes(.*)$": "<rootDir>/src/themes",
      "api": "<rootDir>/src/api.js",
    }
  }
}

这是因为 Yarn 控制了解析管道,因此不知道来自第三方配置的解析指令(如 moduleNameMapper)。

但这并不是说您没有选择,具体来说,这里的修复是为了避免 moduleNameMapper,而是利用内置的 link: 依赖协议。这还有其他优点,例如与所有工具(TS、Jest、ESLint 等)兼容,无需将别名移植到每种配置格式。

另请参阅:为什么建议使用 link: 协议而不是路径映射的别名?