Babel和Jest配置:SyntaxError:无法在模块外部使用import语句。

5

我正在开发一个使用lit element编写的JS Web组件的Ruby on Rails 7应用程序。我正在尝试将Jest添加到项目中,以便我们可以对Web组件进行单元测试。

不使用Typescript,只使用原生JS。我正在运行node v18.12.1,npm v9.2.0。

我按照官网上的初始Jest入门步骤进行操作:

npm install --save-dev jest

然后在package.json中添加了"scripts": { "test": "jest" }

我创建了一个简单的测试来尝试它,没有出现错误。

但是,一旦我为其中一个导入lit的自定义Web组件添加了一个测试(import {LitElement} from 'lit';),我就会得到以下错误:

Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
      If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
      If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
      To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
      If you need a custom transformation specify a "transform" option in your config.
      If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /home/app/service/app/javascript/test/utils/validators.test.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { IsNumber } from '../../utils/validators.js';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1495:14)

阅读错误信息(并在此处和谷歌博士的帮助下进行检查),似乎使用Babel是正确的方法。因此,我前往Jest的Babel安装页面,并按照他们的说明进行了操作:

npm install --save-dev babel-jest

然后添加到package.json中:

  "jest": {
    "transform": {
      "^.+\\.[t|j]sx?$": "babel-jest"
    }
  },
}

然后安装了 Babel 预设环境:

npm install @babel/preset-env --save-dev

并添加 babel.config.json

{
  "presets": ["@babel/preset-env"]
}

我仍然得到相同的错误。

我的 package.json

{
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "transform": {
      "^.+\\.[t|j]sx?$": "babel-jest"
    }
  },
  "devDependencies": {
    "@babel/preset-env": "^7.20.2",
    "babel-jest": "^29.4.3",
    "jest": "^29.4.3",
    "lit": "^2.6.1"
  }
}

我的 babel.config.json:

{
  "presets": ["@babel/preset-env"]
}

失败的测试:

import {SomeFunction} from '/a-valid-path/my-custom.js';

describe('some tests', () => {
  test('a test', () => {
    expect(SomeFunction(some-value)).toBe(true);
  });
});

在 stack overflow 上有其他关于这个问题的帖子。提供的解决方案似乎都表明我需要在 package.json 中的 jest 配置(或对于具有单独的 jest 配置文件的人来说,是 jest.config.js)中添加一些 transformtransformIgnorePatterns 设置,以便正确进行转译。

例如 这里 推荐的解决方案是:

"transform": {
      "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest" //I swapped in 'babel-jest' here
    },
    "transformIgnorePatterns": [
      "node_modules/(?!variables/.*)"
    ]

这就是这里

  transform: {
    "^.+\\.(js|ts)$": "ts-jest",
  },
  transformIgnorePatterns: [
    "node_modules/(?!lit-html)",
  ],

这里的解决方案是在package.json中添加"type": "module"

我在这里和其他网站找到的所有解决方案都没有起作用。我一直收到相同的错误。

有没有人知道我漏掉了什么?

2个回答

6

经过一些尝试和错误,我最终通过在package.json中设置:"transformIgnorePatterns": []来解决了它。

似乎即使我没有给它一个值,该设置也必须存在。完全删除transformIgnorePatterns会导致相同的错误。

最终的工作配置:

Package.json:

{
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "transform": {
      "^.+\\.(js|ts)$": "babel-jest"
    },
    "transformIgnorePatterns": []
  },
  "devDependencies": {
    "@babel/preset-env": "^7.20.2",
    "babel-jest": "^29.4.3",
    "jest": "^29.4.3",
    "lit": "^2.6.1"
  }
}

Babel.config.json:

{
  "presets": ["@babel/preset-env"]
}

0
我遇到了完全相同的问题,只是依赖项是url-exist而已。
我尝试了各种方法(包括你的解决方案),但都没有效果,直到我意识到问题出在我在单元测试中模拟模块的方式上。
我按照Jest文档中的自动模拟方式进行了尝试。
import urlExist from "url-exist";

jest.mock("url-exist"); // WRONG, Jest will complain

问题终于在我添加了moduleFactory参数后得到解决:
import urlExist from "url-exist";

jest.mock("url-exist", () => jest.fn()); // Working now, phew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接