【问题标题】:Jest setup "SyntaxError: Unexpected token export"开玩笑设置“SyntaxError:意外的令牌导出”
【发布时间】:2017-07-04 18:05:20
【问题描述】:

我正在对当前没有测试的现有项目实施测试。我的测试无法编译 node_modules/ 导入。

/Users/me/myproject/node_modules/lodash-es/lodash.js:10
export { default as add } from './add.js';
^^^^^^
SyntaxError: Unexpected token export
  
  at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:320:12)
  at Object.<anonymous> (app/reducers/kind_reducer.js:2:43)
  at Object.<anonymous> (app/reducers/index.js:12:47)

我发现的解决方法是在 package.json jest 配置中将node_modules 列入“白名单”,如下所示:

"jest": {
    "transformIgnorePatterns": [
      "!node_modules/"
    ]
  }

这似乎是个 hack,因为运行一个导入 node_modules/lodash-es/lodash.js 的简单测试需要 1 分钟多的时间。

【问题讨论】:

  • 很多节点模块都导出 ES5,这样 jest 可以直接运行它而无需转换。这就是为什么默认情况下 jest 不会转换 node_modules。在这种情况下,lodash-es 专门导出 es 模块,因此您必须让 jest 转换该代码。如果您在 transformIgnorePatterns 中使用 "!node_modules/lodash-es" 来代替 jest 仅在 lodash-es 上运行 babel,您可能是安全的。

标签: reactjs redux jestjs


【解决方案1】:

如果上述解决方案都不适合您,您可以开玩笑地尝试一下

"moduleNameMapper": {
    "^lodash-es$": "lodash"
}

它将在测试运行时将lodash-es替换为commonjs版本。

【讨论】:

  • 我讨厌这是唯一对我有用的答案。必须有比两次将 lodash 作为依赖项更好的方法
  • @jamesthollowell 您不必直接依赖它,因为您很可能已经通过另一个软件包深深地依赖它。我真的不建议这样做,但如果你不想在你的 pkg.json 中有另一个条目,你可以这样做。
  • 谢谢,这是唯一对我有用的解决方案。 transformIgnorePatterns 方法对我不起作用。
  • @jamesthollowell,你只需要lodash in devDependencies,用于测试。所以它不会影响您的捆绑包大小。您仍然可以在整个应用程序中使用 lodash-es 导入。
  • 此解决方案似乎比transformIgnorePatterns 快得多。 (我的测试套件运行这个大约需要 17 秒,使用 transformIgnorePatterns 运行大约需要 23 秒。)
【解决方案2】:

我必须将此添加到我的.jestconfig

"transformIgnorePatterns": [
  "<rootDir>/node_modules/(?!lodash-es)"
]

【讨论】:

  • 这个可行,但我必须安装babel-jestbabel-preset-envbabel-preset-react,然后是"transform": { "^.+\\.(js|jsx|mjs)$": "&lt;rootDir&gt;/node_modules/babel-jest" },因为ts和js文件需要不同的转换。
  • 如果您有多个,您可能需要包含在同一个正则表达式中,例如(?!lodash-es|my-module)。出于某种原因,如果它们在单独的条目中,它们会相互抵消。
  • 他们必须在同一个条目中,因为 jest 文档中的这个语句。 “如果测试路径匹配任何模式,它将不会被转换。”因此,当 my-module 进行测试时,它会为 ?!lodash-es 正则表达式测试 true,然后将其忽略。
  • 扩展 Jazzy 的评论:如果您已经有一个transformIgnorePatterns: [ 'node_modules/(?!foo|bar)' ] 条目,那么您必须将lodash-es 添加到该列表;您不能在 transformIgnorePatterns 数组中添加单独的条目,因为现有条目已经意味着“忽略 node_modules 下的所有文件夹,除了 foo 和 bar”,因此 node_modules/lodash-es 将被忽略。 // 提示(来自github issue comment):如果使用jest.config.js,你可以先const esModules = ['foo', 'bar', 'lodash-es'] 然后esModules.join('|')
  • 注意:如果你已经运行了jest --watch,你必须退出并重新运行 jest 才能看到transformIgnorePatterns 的更改生效。
【解决方案3】:

在这里发布更完整的答案:

默认情况下,Jest 不会转换 node_modules,因为 node_modules 很大。大多数节点模块被打包以暴露 ES5 代码,因为它无需任何进一步的转换即可运行(并且很大程度上向后兼容)。

在您的情况下,lodash-es 专门公开了 ES 模块,这些模块需要由 Jest 通过 babel 构建。

您可以尝试缩小白名单,这样 Jest 就不会尝试通过 babel 传递 node_modules 中的每个 JavaScript 文件。

我认为您的正确配置是:

"jest": {
  "transformIgnorePatterns": [
    "/!node_modules\\/lodash-es/"
  ]
}

【讨论】:

    【解决方案4】:

    对于正在寻找修复程序的create-react-app 用户,这对我有用:

    // package.json
    ...
      "jest": {
        "transformIgnorePatterns": [
          "<rootDir>/node_modules/(?!lodash-es)"
        ]
      },
    ...
    

    jest.config.js 文件中的覆盖选项对我不起作用。请记住,并非每个选项都可以被覆盖,以下是支持的选项列表:https://create-react-app.dev/docs/running-tests#configuration

    【讨论】:

    • 谢谢伙计。解决了我的问题
    【解决方案5】:

    将 .babelrc 重命名为 babel.config.js 并添加 transformIgnorePatterns 对我有用。

    module.exports = {
      "presets": ["@babel/preset-env"]
    }
    

    附:我的笑话版本是: “笑话”:“24.9.0”

    https://github.com/facebook/jest/issues/6229#issuecomment-419885857

    【讨论】:

      【解决方案6】:

      可能有人觉得这很有用:

      就我而言,我有一个使用 lodash-es 包的 Angular 应用程序。在测试过程中,我遇到了和作者一样的错误。

      OPatel 的回答对我来说很好,只需稍加调整(将其添加到您的 jest.config.ts):

      "moduleNameMapper": {
          "lodash-es": "lodash"
      }
      

      更改后,我还需要将"esModuleInterop": true 添加到tsconfig.spec.json 中的compilerOptions 属性中,以摆脱TypeError: cloneDeep_1.default is not a function

      更新:

      在上述所有 lodash 方法的解决方案之后,返回 LodashWrapper 而不是实际值,例如

      const clone = cloneDeep(object); // LodashWrapper
      

      为了摆脱这个问题,我使用了这个解决方案: https://github.com/nrwl/nx/issues/812#issuecomment-787141835

      moduleNameMapper: {
          "^lodash-es/(.*)$": "<rootDir>/node_modules/lodash/$1",
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-10
        • 1970-01-01
        • 2017-09-13
        • 1970-01-01
        • 2021-03-08
        • 2021-10-28
        • 2019-01-30
        • 2021-11-12
        相关资源
        最近更新 更多