如何忽略 Next.js 组件中导致单元测试中的解析错误的 CSS 模块导入

Posted

技术标签:

【中文标题】如何忽略 Next.js 组件中导致单元测试中的解析错误的 CSS 模块导入【英文标题】:How do I ignore CSS Module imports in a Next.js component that cause parse errors in unit tests 【发布时间】:2020-10-20 05:36:06 【问题描述】:

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

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

组件文件

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)

【问题讨论】:

【参考方案1】:

您需要将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 替换为一个空对象,因为无论如何您都不应该使用单元测试来测试您的样式。 (你应该使用visual regression tests。)

【讨论】:

【参考方案2】:

进一步挖掘,有一个ignore-styles 包,您可以将其用作-r @babel/register -r ignore-styles,这似乎使它起作用。不确定这是否是最佳选择,但它让我畅通无阻。我仍然愿意接受其他答案。

【讨论】:

以上是关于如何忽略 Next.js 组件中导致单元测试中的解析错误的 CSS 模块导入的主要内容,如果未能解决你的问题,请参考以下文章

带有 Next.js 10.0.3 的 Tailwind CSS(PostCSS 插件)在开发环境中导致 Javascript 堆内存不足错误

在 Next/React 组件中导入 global vs getStaticProps

JPA 在 Spring Boot 中导致 java.lang.NullPointerException

next.js + expo:您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入

EDT违规是否可能在外部软件中导致NullPointerException?

交叉表和混淆矩阵在 Python 中导致不一致