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

Vitest测试Svelte组件遇‘Function called outside component initialization’错误

问题解决:Svelte组件测试时Function called outside component initialization错误

问题现象

使用Vitest测试倒计时Svelte组件时,执行import Countdown from "../lib/Countdown.svelte"导入操作就触发错误:Function called outside component initialization,报错指向onDestroy调用。

错误原因

  1. 生命周期函数调用时机错误:组件中使用了<script context="module">模块级脚本,该脚本在组件被导入时就会执行,而onDestroy是组件实例的生命周期函数,只能在组件实例初始化阶段调用,模块脚本执行时还未创建组件实例,因此触发错误。
  2. 变量作用域问题:模块级脚本中的变量(如time、running)是所有组件实例共享的,多个实例会互相干扰倒计时逻辑,不符合组件独立性要求。

修复步骤

  1. 移除脚本的context="module"属性,将模块级脚本改为普通组件脚本,确保变量和生命周期函数属于单个组件实例。
  2. 导入onMount生命周期函数,将startCountdown()的调用放在onMount中,确保组件初始化完成后再启动倒计时。
  3. 保留onDestroy逻辑,用于组件销毁时停止倒计时。

修改后的组件代码

<script>
    import {push} from 'svelte-spa-router'
    import {onDestroy, onMount} from 'svelte'

    let time = 1000*120;
    let interval = 1000;
    let running = true;
        
    const twoDigits = (number) => {
        return number.toLocaleString('en-US', {
            minimumIntegerDigits: 2,
            useGrouping: false
        })
    }
    
    const timeString = (ms) => {
        let seconds = ms / 1000;
        const minutes = Math.floor(seconds / 60);
        seconds = seconds % 60;
        const timeString = twoDigits(minutes) + ":" + twoDigits(seconds);
        return timeString
    }
    
    let timeShown = timeString(time)
    
    const startCountdown = () => {
        setTimeout(()=>{
            time -= interval;
            timeShown = timeString(time);
            if (time > 0 && running) {
                startCountdown();
            } else if (time > 0 && !running) {
                console.log("Countdown stopped")
            } else {
                console.log("Done!")
                setTimeout( () => {
                    push('/gameover')
                },1000)
            }
        }, interval)
    }

    onMount(() => {
        startCountdown()
    })

    onDestroy(()=>{
        running = false;
    })

</script>

<div id="countdown">
    {timeShown}
</div>

测试文件与配置说明

  • 测试文件无需修改,导入组件后可正常执行测试。
  • vite.config.js配置保持不变即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:34:59