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

使用Jest测试Vue3组件时出现‘缺少模板或渲染函数’错误

Vue3组件单元测试报错:Component is missing template or render function 解决方法

问题描述

将基于Webpack搭建的Vue2项目升级为Vue3后,项目可正常构建运行,但组件单元测试执行时弹出如下警告,随后测试失败:

console.warn
[Vue warn]: Component is missing template or render function.
at
at

已将组件简化为最小可复现示例(移除Script Setup语法、保留基础template和defineComponent),测试代码也改为最基础形式,但问题依旧。非组件类测试(如Composable测试)可正常通过,推测是Vue组件未被Jest正确转换。

关键代码片段

简化后的组件(CloseButton.vue)

<template>
    <p>Hey what is up</p>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
    setup() {},
});
</script>

<style scoped>
svg.close-icon {
    height: 1.125em;
    width: 1.125em;
}

.close-button {
    border: none;
    background: none;
    padding: 0;
    cursor: pointer;
}
</style>

测试代码(CloseButton.spec.js)

import CloseButton from '/components/CloseButton/CloseButton.vue';
import { mount } from '@vue/test-utils';

describe('CloseButton.vue', () => {
    it('renders the close button', () => {
        const wrapper = mount(CloseButton, {});

        expect(wrapper.find('p').exists()).toBe(true);
    });
});

Jest配置(jest.config.js)

/** @type {import('@jest/types').Config.InitialOptions} */
const config = {
    verbose: true,
    moduleDirectories: ['node_modules', 'src'],
    moduleFileExtensions: [
        'js',
        'json',
        'ts',
        'tsx',
        'vue',
    ],
    transform: {
        '.*\\.(vue)$': '@vue/vue3-jest',
        '.*\\.(js)$': 'babel-jest',
        '^.+\\.tsx?$': 'ts-jest',
        '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)(\\?inline)?$': 'jest-transform-stub',
    },
    moduleNameMapper: {
        '^/components/(.*)$': '<rootDir>/src/components/$1',
        '^@/(.*)$': 'src',
    },
    testEnvironment: 'jsdom',
    collectCoverage: true,
    coverageReporters: ['json', 'html'],
    collectCoverageFrom: ['**/*.{js,ts,vue}', '!**/node_modules/**'],
    coveragePathIgnorePatterns: [
        'dist',
        'node_modules',
        'build',
        'config',
        'coverage',
        '.eslintrc.js',
        '.postcssrc.js',
        'tests',
        'main.js',
    ],
    snapshotSerializers: ['jest-serializer-vue'],
    reporters: ['default', 'jest-junit'],
    testEnvironmentOptions: {
        customExportConditions: ['node', 'node-addons'],
    },
};

module.exports = config;

解决步骤

1. 对齐依赖版本兼容性

确保@vue/vue3-jest、@vue/test-utils、vue和jest的版本匹配:

  • Vue 3.x 需搭配 @vue/test-utils@2.x 和 @vue/vue3-jest(版本号需与Jest主版本一致,比如Jest 29对应@vue/vue3-jest@29.x)
  • 示例package.json依赖片段:
{
  "dependencies": {
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vue/test-utils": "^2.4.1",
    "@vue/vue3-jest": "^29.2.6",
    "jest": "^29.7.0",
    "ts-jest": "^29.1.1"
  }
}

2. 修正Jest配置错误

(1)修复路径映射

moduleNameMapper中^@/(.*)$的映射路径错误,需改为<rootDir>/src/$1,与组件路径映射保持一致:

moduleNameMapper: {
    '^/components/(.*)$': '<rootDir>/src/components/$1',
    '^@/(.*)$': '<rootDir>/src/$1', // 修正此处
},

(2)调整转换器顺序

将.vue文件的转换器移到transform配置最顶端,确保优先处理:

transform: {
    '.*\\.(vue)$': '@vue/vue3-jest', // 移至最前
    '^.+\\.tsx?$': 'ts-jest',
    '.*\\.(js)$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)(\\?inline)?$': 'jest-transform-stub',
},

(3)移除Vue2残留配置

  • jest-serializer-vue是Vue2的快照序列化工具,Vue3测试无需配置,直接删除该字段:
// 移除此行
// snapshotSerializers: ['jest-serializer-vue'],
  • 移除testEnvironmentOptions中的customExportConditions,避免干扰Vue3的导出解析:
// 移除此块
// testEnvironmentOptions: {
//     customExportConditions: ['node', 'node-addons'],
// },

3. 优化测试文件导入路径

将测试中的绝对路径改为别名路径,符合项目配置习惯:

import CloseButton from '@/components/CloseButton/CloseButton.vue';

4. 检查Babel配置(若存在)

确保babel.config.js支持Vue3语法,示例配置:

module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { node: 'current' } }]
  ]
};

验证修复

执行单元测试命令,若警告消失且测试通过,则问题解决。

内容的提问来源于stack exchange,提问作者tommy-preston-envolve

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 07:32:01