在nx monorepo中运行Jest时出错:SyntaxError: Unexpected token 'export'。

10

背景

我有一个使用Nx构建的单一代码库项目。这个代码库包含了多个后端项目可重用的库。这些库是从多个项目中收集而来,以创建一个可重用的库。

我使用 Jest 创建和运行在我的 monorepo 中使用的单元测试。

问题

当我运行 Jest 时,会在一些测试中抛出关于无法导入具有export的 .js 文件的错误。

奇怪的是,这些模块有一个 commonjs 版本,我可以在其他没有 monorepo 结构的项目中轻松地模拟这些包。但是,当我在 monorepo 项目中使用相同的代码时(我想要使代码可重用),Jest 错误地导入了包的 ESM 版本而不是 CJS 版本。

用例:

  • 我有一个 Blob 存储库,它在内部使用ali-oss
  • ali-oss 在同一个包中分发了 CJS 和 ESM,并且我可以在其他项目中(不使用 monorepo)轻松地模拟它
  • 当我将相同的库复制到我的新 monorepo 中时,Jest 将抱怨node_modules中的ali-oss源代码中有关于 export 标记的问题

为什么 Jest 在 monorepo 和正常 repo 中的行为不同?如何解决这个奇怪的 jest 模块解析问题?

文件

tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "forceConsistentCasingInFileNames": true,
    "strict": false,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  },
  "files": [],
  "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
}

jest.config.ts:

const nxPreset = require("@nrwl/jest/preset").default;

export default {
  ...nxPreset,
  clearMocks: true,
  coverageReporters: ["lcov", "text", "text-summary", "json-summary"],
  displayName: "kafka",
  globals: {
    "ts-jest": {
      tsconfig: "<rootDir>/tsconfig.spec.json",
    },
  },
  testEnvironment: "node",
  transform: {
    "^.+\\.[tj]s$": "ts-jest"
  },
  moduleFileExtensions: ["ts", "js"],
  coverageDirectory: "../../coverage/packages/kafka",
};

单元测试:

import Bull from "bull";

import * as dlq from "../src/dlq";
import { ModuleContext} from "./context";

jest.mock("bull");

describe(ModuleContext.Root, () => {
  describe(ModuleContext.Runner, () => {
    it("success", () => {
      expect(true).toBe(true);
    })
    describe(dlq.initialize.name, () => {
      it("should return success", () => {
        const createSpy = jest
          .spyOn(Bull.prototype, "process")
          .mockResolvedValue(null);

        dlq.initialize();
        expect(createSpy).toBeCalled();
      });
    });
  });
});

Jest 输出:

 FAIL   kafka  packages/kafka/test/dlq.spec.ts
   Test suite failed to run

    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/fahmi/logee/logee-ct/logeect-libraries-monorepo/node_modules/.pnpm/msgpackr@1.6.2/node_modules/msgpackr/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { Packr, Encoder, addExtension, pack, encode, NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT, REUSE_BUFFER_MODE } from './pack.js'
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

      at Runtime.createScriptFromCode (../../node_modules/.pnpm/jest-runtime@28.1.3/node_modules/jest-runtime/build/index.js:1796:14)
      at Object.<anonymous> (../../node_modules/.pnpm/bull@4.8.5/node_modules/bull/lib/scripts.js:8:18)

我有一个非常类似的问题,但它只发生在我的机器上。你能解决这个问题吗? - theOwl
不,我还没有解决这个问题。目前我跳过了那些有问题的文件。 - Fahmi Noor Fiqri
我目前也遇到了同样的问题。有任何更新吗? - andersbs
1个回答

3

按照此处描述的 Nx 迁移步骤,我成功地避免了该错误。

npx nx migrate latest
npx nx migrate --run-migrations

您可以在更新后的文件中看到,Nx会自动使用以下转换字段更新jest配置:
  transform: {
    '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest', // My config from before
    '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }], // Added by Nx under the migration
  },

希望这能帮到您。

1
谢谢你的见解,但我目前没有使用React。 - Fahmi Noor Fiqri
我已经安装了最新版本的 nx,也就是说运行 npx nx migrate latest 没有创建任何迁移文件(它是这样说的)。然而,你的回答解决了我的问题。我更新了所有应用程序中的 jest.config.ts 文件以匹配你的代码片段,然后它就可以工作了。 谢谢。 - Sadra Abedinzadeh
我在 jest.config.ts 中进行了更新,解决了在我的 IntelliJ IDE 中无法运行测试但使用 nx run 运行时正常的问题。不需要完全迁移和升级 nx。 - dijonkitchen

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