typescript - Vitest defineConfig, 'test' אינו קיים בסוג 'UserConfigExport'


מנסים להגדיר את vitest על פרויקט vite קיים (vue 3, typescript).

vite.config.ts שלי נראית כך:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
  },
  plugins: [vue()],
});

אבל ב-VS קוד זה מתלונן:

כאשר אני מרחף אני רואה:

הארגומנט מסוג '{ test: { globals: boolean; environment: string; }; plugins: Plugin[]; }' אינו ניתן להקצאה לפרמטר מסוג 'UserConfigExport'. ניתן לציין באובייקט מילולי רק מאפיינים ידועים, ו-'test' אינו קיים בסוג 'UserConfigExport'.ts(2345)

אני יכול לגרום לזה להיעלם אם אני אשנה את השורה הזו:

import { defineConfig } from 'vite';

אל :

import { defineConfig } from 'vitest/config';

אבל למה? מה קורה עם זה? למה אני צריך לייבא defineConfig מ-vitest כדי שזה יתמוך בתכונת ה-test?

תשובה #1

תשובה קצרה:

כי ככה TypeScript עובד. ממשק התצורה של Vite אינו יודע שום דבר על Vitest ו-TS לא מאפשר תכונות מיותרות (תכונות שלא מוגדרות על ידי הסוג/הממשק)

לכן Vitest חייב להרחיב את תצורת Vite (המוגדרת כממשק TS). כדי להשתמש בממשק המורחב הזה במקום המקורי, עליך קודם כל לייבאו.

במקום לעשות זאת (ייבוא קונפיגורציית Vite טהורה):

import { defineConfig } from 'vite';

עשה זאת (ייבוא קונפיגורציית Vite מורחבת על ידי Vitest):

import { defineConfig } from 'vitest/config';

לחלופין, אתה יכול גם להשתמש בפקודת TS triple slash כפי שמתועד בניהול קובץ ההגדרות של Vitest

/// <reference types="vitest/config" />
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    // ...
  },
})

אם אתה משתמש בגרסת Vitest ישנה מ-2.1:

/// <reference types="vitest" />

תשובה #2

אני הפרדתי את הקבצים כי קיבלתי אותם מהשאלה הזו ואם שיניתי את הייבוא ל-vitest קיבלתי שגיאה אחרת בשורת התוסף react.

  • vite.config.ts
  • vitest.config.ts

ויטסט :

import { defineConfig } from 'vitest/config';

    export default defineConfig({
        test: {
          globals: true,
          environment: 'jsdom'
        },
      })

מהר :

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
  },
})

תשובה #3

הנה מה שעשיתי למקרה שמישהו עדיין מחפש פתרון. יצרתי את הסוג שלי והרחבתי ל-UserConfig.

...
import type { InlineConfig } from 'vitest';
import type { UserConfig } from 'vite';

interface VitestConfigExport extends UserConfig {
  test: InlineConfig;
}
...

אז המירתי את סוג האובייקט config לממשק המותאם אישית שלי -

export default defineConfig({
  plugins: [solidPlugin()],
  server: {
    port: 3000,
  },
  test: {
    environment: 'jsdom',
    globals: true,
    transformMode: {
      web: [/\.[jt]sx?$/],
    },
    setupFiles: './setupVitest.ts',
  },
  build: {
    target: 'esnext',
  },
} as VitestConfigExport);

זה גם אפשר אינטלי-סנס לנכס החדש test. גם, אין צורך להכריז על /// <reference types="vitest" />. זה עשוי לעזור.

תשובה #4

אנחנו יכולים להשתמש בשיטה mergeConfig מתוך ערכי vite או vitest/config כדי למזג את קונפיגורציית Vite עם קונפיגורציית Vitest:

import { defineConfig as defineViteConfig, mergeConfig } from 'vite';
import { defineConfig as defineVitestConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';

const viteConfig = defineViteConfig({
  plugins: [react()],
});

const vitestConfig = defineVitestConfig({
  test: {
    // ...
  },
});

export default mergeConfig(viteConfig, vitestConfig);

תשובה #5

הייתי במצב דומה, שואל את עצמי את אותו הדבר ובסוף עושה את זה:

/// <reference types="vitest" />
import { defineConfig } from 'vite';
import type { UserConfig as VitestUserConfigInterface } from 'vitest/config';

const vitestConfig: VitestUserConfigInterface = {
  test: {
    // vitest config, with helpful vitest typing :)
  }
};

export default defineConfig({
  test: vitestConfig.test,
  // and now: just vite config
});

זה יכול להיות מועיל.