You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3 Jest测试中导入nextTick等函数出现类型不存在错误

问题

在Jest测试中从Vue3导入nextTick及其他函数时,出现类型错误:

Property 'nextTick' does not exist on type 'typeof import("/Users/XXXXX/dev/XXXXX/src/XXXXX/packages/XXXXX/node_modules/vue/dist/vue")'

测试代码如下:

import * as vue from 'vue';
import useClassNames from './useClassNames';

describe('useClassNames', () => {
  it('render', async () => {
    const result = useClassNames([]);
    await vue.nextTick();
    expect(result).toBe([]);
  });
});

实际运行时nextTick是存在的,Object.keys(vue)能查到该属性,但无论是全量导入、默认导入还是按需导入都会报类型错误,导入h等其他函数也有同样问题。

项目配置信息

已安装依赖

{
  "version": "0.1.0",
  "private": false,
  "scripts": {
    "test-with-coverage": "COLLECT_TEST_COVERAGE=TRUE jest",
    "test": "jest"
  },
  "engines": {
    "node": ">=14.0.0"
  },
  "dependencies": {
    "vue": "^3.2.37"
  },
  "devDependencies": {
    "@testing-library/dom": "^8.14.0",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/user-event": "^14.2.1",
    "@types/jest": "^27.0.2",
    "@types/jest-axe": "^3.5.4",
    "@types/node": "^16.11.6",
    "@typescript-eslint/eslint-plugin": "^4.28.3",
    "@typescript-eslint/parser": "^4.28.3",
    "@vitejs/plugin-vue": "2.3.3",
    "@vue/test-utils": "^2.0.0",
    "@vue/vue3-jest": "26.0.1",
    "babel-jest": "^26.6.3",
    "eslint": "^7.31.0",
    "eslint-plugin-jest": "^24.3.6",
    "eslint-plugin-prettier": "^3.4.0",
    "eslint-plugin-vue": "^9.1.1",
    "jest": "~26.6.3",
    "jest-axe": "^6.0.0",
    "prettier": "2.1.2",
    "sass": "^1.52.2",
    "ts-jest": "~26.3.0",
    "typescript": "4.0.8",
    "vite": "^2.9.10",
    "vue-tsc": "0.37.0"
  }
}

Jest配置

const collectCoverage = process.env.COLLECT_TEST_COVERAGE === 'TRUE';

module.exports = {
  testEnvironment: 'jsdom',
  moduleDirectories: ['node_modules', 'src'],
  moduleFileExtensions: ['vue', 'ts', 'js'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
  transform: {
    '^.+\\.vue$': '@vue/vue3-jest',
    '^.+\\.js$': 'babel-jest',
    '^.+\\.ts$': 'ts-jest',
  },
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  collectCoverage,
  collectCoverageFrom: ['src/{components,hooks}/**/*.{js,ts,vue}'],
  coverageReporters: ['html', 'text-summary'],
  coverageDirectory: '<rootDir>/coverage',
  coverageThreshold: {
    global: {
      statements: 80,
      branches: 80,
      functions: 80,
      lines: 80,
    },
  },
};

tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": [
      "ESNext",
      "DOM",
      "dom.iterable"
    ],
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "jest.setup.ts",
  ],
  "references": [
    {
      "path": "./tsconfig.node.json"
    }
  ]
}

tsconfig.node.json

{
  "compilerOptions": {
    "composite": true,
    "module": "ESNext",
    "moduleResolution": "Node"
  },
  "include": [
    "vite.config.ts"
  ]
}

解决方案

1. 修正Vue导入方式并调整断言逻辑

Vue3的ESM模块中,nextTick等工具函数是具名导出,直接按需导入即可,同时注意数组断言的正确写法:

import { nextTick } from 'vue';
import useClassNames from './useClassNames';

describe('useClassNames', () => {
  it('render', async () => {
    const result = useClassNames([]);
    await nextTick();
    expect(result).toEqual([]); // 数组需用toEqual而非toBe,toBe是严格引用相等
  });
});

2. 调整TypeScript模块解析配置

当前moduleResolution设为Node,对ESNext模块的解析存在兼容问题,修改为适配打包工具的配置:
在tsconfig.json的compilerOptions中更新:

"moduleResolution": "NodeNext",
"allowSyntheticDefaultImports": true

若使用TypeScript 5.0+,推荐改用"moduleResolution": "Bundler",更适配Vite的模块解析逻辑。

3. 强制Jest使用Vue的ESM版本

在Jest配置的moduleNameMapper中添加映射,避免导入到UMD版本:

moduleNameMapper: {
  '^@/(.*)$': '<rootDir>/src/$1',
  '^vue$': 'vue/dist/vue.esm-bundler.js'
},

4. 升级依赖版本(可选)

当前ts-jest和@vue/vue3-jest版本较低,对应Jest 26,升级到适配Vue3的高版本可提升类型兼容性:

npm install ts-jest@^27.0.0 @vue/vue3-jest@^27.0.0 jest@^27.0.0 --save-dev

5. 临时检查Vue类型声明(可选)

若上述方法无效,可临时关闭tsconfig.json中的skipLibCheck,排查是否存在类型声明冲突:

"skipLibCheck": false

排查完成后建议重新开启,避免影响编译速度。


内容的提问来源于stack exchange,提问作者Bong2000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 23:19:01