简体   繁体   English

Jest with TypeScript (Backend - Node/Express) 说 Cannot use import statement outside a module

[英]Jest with TypeScript (Backend - Node/Express) says Cannot use import statement outside a module

I am working on Jest tests for a Node/Express TypeScript backend.我正在为 Node/Express TypeScript 后端进行 Jest 测试。 I recently learnt about global test setup which I am implementing to reduce similar variables and function calls that are executed in all test files.我最近了解了我正在实施的全局测试设置,以减少在所有测试文件中执行的类似变量和 function 调用。
So for example in the below code I want to make the app and userToken global variables and await initDatabase() function called in the tests setup file.⬇因此,例如在下面的代码中,我想使 app 和 userToken 成为全局变量,并等待在测试设置文件中调用的 initDatabase() function。⬇

import initServer from '../initServer';
import { initDatabase } from '../util/databaseHandler';
import loginWithAWS from '../util/loginWithAWS';

const app = initServer();
let userToken: any;

describe(`Test on the GET method of route `, () => {

  beforeAll( async() => {
    try{
      await initDatabase();
      userToken = await loginWithAWS('userRole');
    }catch(error){
      return error;
    }
  });
});

However, after implementing the global test setup with the variables and function then running the test on terminal/bash/cmd via the command yarn test this error is thrown: ⬇但是,在使用变量和 function 实施全局测试设置后,然后通过命令yarn test在终端/bash/cmd 上运行测试,抛出此错误:⬇
抛出错误

The solution in progress which throws the bug is implemented as shown below.抛出错误的正在进行的解决方案如下所示实现。 Your assistance will be highly valued.:您的协助将受到高度重视。:
The test setup file:测试设置文件:
testSetup.ts testSetup.ts

import initServer from '../initServer';
import { initDatabase } from '../util/databaseHandler';
import loginWithAWS from '../util/loginWithAWS';


const initializeTestingSetup = async function() {
  (global as any).app = initServer();
  await initDatabase();
  (global as any).userToken = await loginWithAWS('userRole');
};

module.exports = initializeTestingSetup;

Below is my jest config file for the project's tests:下面是我的项目测试的笑话配置文件:
jest.config.js jest.config.js

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
  transform: {
    '^.+\\.ts$': 'ts-jest',
    '^.+\\.js$': 'babel-jest',
    '^.+\\.mjs$': 'babel-jest',
  },
  moduleDirectories: ['node_modules', '<rootDir>/src'],
  moduleNameMapper: {
    '@controllers/(.*)': '<rootDir>/src/controllers/$1',
    '@middleware/(.*)': '<rootDir>/src/middleware/$1',
    '@models/(.*)': '<rootDir>/src/models/$1',
    '@routes/(.*)': '<rootDir>/src/routes/$1',
    '@types/(.*)': '<rootDir>/src/types/$1',
    '@util/(.*)': '<rootDir>/src/util/$1',
  },
  globals: {
    'ts-jest' : {
      astTransformers: {
        before: [
          'ts-jest/dist/transformers/path-mapping'
        ]
      },
    } 
  },
  globalSetup: './src/__tests__/testSetup.ts',
};

I would really appreciate your help.我将衷心感谢您的帮助。

Jest seems to have problems with ES6 import syntax in any globalSetup scripts. Jest 似乎在任何 globalSetup 脚本中都存在 ES6 导入语法问题。 I would try to change your testSetup.ts script to use require instead of import so it doesn't have to be an ES6 module.我会尝试更改您的testSetup.ts脚本以使用require而不是import因此它不必是 ES6 模块。 Note that you are mixing CommonJS and ES6/ESM syntax in your testSetup.js because you have import , but use module.exports .请注意,您在testSetup.js中混合了 CommonJS 和 ES6/ESM 语法,因为您有import ,但使用module.exports Something like this might work perhaps (this is untested):像这样的东西可能会起作用(这是未经测试的):

const initServer = require('../initServer');
const initDatabase = require('../util/databaseHandler');
const loginWithAWS = require('../util/loginWithAWS');


const initializeTestingSetup = async function() {
  (global as any).app = initServer();
  await initDatabase();
  (global as any).userToken = await loginWithAWS('userRole');
};

module.exports = initializeTestingSetup;

UPDATE: What about trying to make the globalsetup more compatible with ESM:更新:如何尝试使 globalsetup 与 ESM 更兼容:

import initServer from '../initServer';
import { initDatabase } from '../util/databaseHandler';
import loginWithAWS from '../util/loginWithAWS';

export default async function setup() {
  (global as any).app = initServer();
  await initDatabase();
  (global as any).userToken = await loginWithAWS('userRole');
};

Does that help?这有帮助吗?

Ensure that package.json has the type: module set.确保package.json具有type: module集。 I'm using node14, so I've set my target and lib to have es2020 as suggested here我使用的是 node14,所以我已经按照此处的建议将目标和库设置为es2020

The tsconfig for tests:用于测试的 tsconfig:

{
  "compilerOptions": {
    "allowUnreachableCode": false,
    "declaration": true,
    "target": "es2020",
    "lib": ["es2020"],
    "importHelpers": true,
    "incremental": true,
    "module": "es2020",
    "esModuleInterop": true,
    "moduleResolution": "Node",
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": true,
    "noImplicitOverride": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "resolveJsonModule": true,
    "sourceMap": true,
    "target": "es2020"
  },
  "include": ["test"],
  "exclude": ["build", "node_modules"]
}

I've set esModuleInterop to avoid any issues that might occur with default imports and set module to es2020 (which allows for import.meta for __dirname).我设置esModuleInterop以避免默认导入可能出现的任何问题,并将module设置为es2020 (允许 import.meta 用于 __dirname)。

We can ask the jest config to treat modules as esm:我们可以要求 jest 配置将模块视为 esm:

{
  "preset": "ts-jest",
  "testEnvironment": "node",
  "testMatch": ["<rootDir>/test/**/*.test.ts"],
  "rootDir": ".",
  "extensionsToTreatAsEsm": [".ts"],
  "globalSetup": "<rootDir>/test/setup.ts",
  "globals": {
    "ts-jest": "./tsconfig.tests.json"
  }
}

In your global setup, stick to esm exports and imports:在您的全局设置中,坚持使用 esm 导出和导入:

import express from "express";
import bodyParser from "body-parser";
import morgan from "morgan";
import helmet from "helmet";
import cors from "cors";
import PicoDb from "picodb";

const app = express();

const logger = morgan("combined");

const jsonParser = bodyParser.json();
const queryParser = bodyParser.urlencoded({ extended: true });

app.use(logger);
app.use(helmet());

app.use(queryParser);
app.use(jsonParser);

app.use(cors());
app.options("*", cors());

export { app };

export default async function globalSetup() {
  const db = new PicoDb();
  await db.insertMany([{ a: 1 }, { a: 2, b: 2 }]);
  app.listen(3000, () => {
    console.log("Server listening on port 3000");
  });
}

This worked as expected when I was running the tests (with jest not exiting because I did not close the server in a teardown step).这在我运行测试时按预期工作(开玩笑没有退出,因为我没有在拆卸步骤中关闭服务器)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法在后端使用 typescript 的模块外部使用导入语句 - Cannot use import statement outside a module using typescript on backend Jest 无法使用 Typescript 导入(语法错误:无法在模块外使用导入语句) - Jest fails to import with Typescript (SyntaxError: Cannot use import statement outside a module) 开玩笑说不能在模块外导入 - jest says cannot import outside a module node-fetch 3.0.0 和 jest 给出了 SyntaxError:不能在模块外使用导入语句 - node-fetch 3.0.0 and jest gives SyntaxError: Cannot use import statement outside a module 不能使用 jest 在模块 node.js 之外使用 import 语句 - Cannot use import statement outside a module node.js using jest Jest 或 Mocha 与 Vue:SyntaxError:无法在模块外使用 import 语句 - Jest or Mocha with Vue: SyntaxError: Cannot use import statement outside a module 开玩笑的单元测试 - SyntaxError:不能在模块外使用 import 语句 - Jest unit test - SyntaxError: Cannot use import statement outside a module Jest - SyntaxError: 无法在模块外使用 import 语句 - Jest - SyntaxError: Cannot use import statement outside a module Typescript 与 mocha - 无法在模块外使用导入语句 - Typescript with mocha - Cannot use import statement outside a module Typescript &amp; TypeORM:不能在模块外使用导入语句 - Typescript & TypeORM: Cannot use import statement outside a module
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM