首页 > 解决方案 > 如何忽略在单元测试中导致解析错误的 Next.js 组件中的 CSS 模块导入

问题描述

我在 Next.js 项目中使用 CSS 模块(我是 Next.js 的新手)并使用Riteway进行测试。当我为 React 组件运行单元测试时,任何导入 CSS 模块的组件都会失败并出现 SyntaxError,因为它无法解析正在导入的 CSS 文件。我已经必须创建一个.babelrc文件来处理测试中的 JSX 解析,以便它复制 Next.js 配置 ( { "presets": ["next/babel"], "plugins": [] }) 并在我的测试命令中使用它来激活它-r @babel/register,但它似乎没有处理 CSS 模块。

如何将我的代码配置为至少不会阻塞 CSS 模块导入并使其成为styles一个import styles from './styles.module.css';空对象,以便所有styles.myClass引用都不会中断?不幸的是,似乎没有任何关于与其他运行上下文(如单元测试)共享 Babel 配置的文档,只有在需要时如何自定义 Babel 配置

组件文件

import React from 'react';

import styles from './styles.module.css'`;

export default () => (
  <div className={styles.root}>
    Content
  </div>
);

组件 CSS 模块

.root {
  background: green;
}

组件测试文件

import React from 'react';
import { describe } from 'riteway';
import render from 'riteway/render-component';

import MyComponent from './component.jsx';

describe('<MyComponent>', async assert => {
  const $ = render(<MyComponent />);

  assert({
    given: 'rendering the component',
    should: 'render',
    actual: $('body > div').length,
    expected: 1,
  });
});

测试命令

$ NODE_ENV=test riteway -r @babel/register -r regenerator-runtime src/path/to/component.test.jsx

测试命令结果

(function (exports, require, module, __filename, __dirname) { .root {
                                                              ^

SyntaxError: Unexpected token '.'
    at new Script (vm.js:84:7)
    at createScript (vm.js:258:10)
    at Object.runInThisContext (vm.js:306:10)
    at Module._compile (internal/modules/cjs/loader.js:880:26)
    at Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Object.newLoader [as .js] (/path/to/app/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Module.require (internal/modules/cjs/loader.js:849:19)
    at require (internal/modules/cjs/helpers.js:74:18)

标签: reactjsunit-testingnext.jscss-modules

解决方案


您需要在您babel-plugin-module-name-mapper的.plugins.babelrc

[
  "module-name-mapper",
  {
    "moduleNameMapper": {
      "\\.css$": "<rootDir>/src/helpers/mock/style-mock.js"
     }
  }
]

这里style-mock.js简单地导出一个空对象。

module.exports = {};

这将做的是,它将用一个空对象替换所有 css,因为无论如何您都不应该使用单元测试来测试您的样式。(您应该为此使用视觉回归测试。)


推荐阅读