[英]Cannot use import statement outside a module using typescript on backend
[英]Jest with TypeScript (Backend - Node/Express) says Cannot use import statement outside a module
我正在为 Node/Express TypeScript 后端进行 Jest 测试。 我最近了解了我正在实施的全局测试设置,以减少在所有测试文件中执行的类似变量和 function 调用。
因此,例如在下面的代码中,我想使 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;
}
});
});
但是,在使用变量和 function 实施全局测试设置后,然后通过命令yarn test
在终端/bash/cmd 上运行测试,抛出此错误:⬇
抛出错误的正在进行的解决方案如下所示实现。 您的协助将受到高度重视。:
测试设置文件:
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;
下面是我的项目测试的笑话配置文件:
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',
};
我将衷心感谢您的帮助。
Jest 似乎在任何 globalSetup 脚本中都存在 ES6 导入语法问题。 我会尝试更改您的testSetup.ts
脚本以使用require
而不是import
因此它不必是 ES6 模块。 请注意,您在testSetup.js
中混合了 CommonJS 和 ES6/ESM 语法,因为您有import
,但使用module.exports
。 像这样的东西可能会起作用(这是未经测试的):
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;
更新:如何尝试使 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');
};
这有帮助吗?
确保package.json
具有type: module
集。 我使用的是 node14,所以我已经按照此处的建议将目标和库设置为es2020
用于测试的 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"]
}
我设置esModuleInterop
以避免默认导入可能出现的任何问题,并将module
设置为es2020
(允许 import.meta 用于 __dirname)。
我们可以要求 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"
}
}
在您的全局设置中,坚持使用 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");
});
}
这在我运行测试时按预期工作(开玩笑没有退出,因为我没有在拆卸步骤中关闭服务器)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.