Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use defu rather than mergeConfig from vite #246

Merged
merged 3 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 69 additions & 68 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Nuxt, NuxtConfig, ViteConfig } from '@nuxt/schema'
import type { InlineConfig as VitestConfig } from 'vitest'
import { defineConfig, mergeConfig } from 'vite'
import { defineConfig } from 'vite'
import type { InlineConfig } from 'vite'
import vuePlugin from '@vitejs/plugin-vue'
import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
Expand Down Expand Up @@ -81,89 +81,90 @@ export async function getVitestConfigFromNuxt(
}
}

return {
...options.viteConfig,
define: {
...options.viteConfig.define,
['process.env.NODE_ENV']: 'process.env.NODE_ENV',
},
server: {
...options.viteConfig.server,
middlewareMode: false,
},
plugins: [
...options.viteConfig.plugins,
{
name: 'disable-auto-execute',
enforce: 'pre',
transform(code, id) {
if (id.match(/nuxt3?\/.*\/entry\./)) {
return code.replace(
/(?<!vueAppPromise = )entry\(\)\.catch/,
'Promise.resolve().catch'
)
}
},
return defu(
// overrides
{
define: {
['process.env.NODE_ENV']: 'process.env.NODE_ENV',
},
],
test: {
...options.viteConfig.test,
dir: process.cwd(),
environmentOptions: {
...options.viteConfig.test?.environmentOptions,
nuxt: {
rootId: options.nuxt.options.app.rootId || undefined,
...options.viteConfig.test?.environmentOptions?.nuxt,
mock: {
intersectionObserver: true,
indexedDb: false,
...options.viteConfig.test?.environmentOptions?.nuxt?.mock,
server: { middlewareMode: false },
plugins: [
{
name: 'disable-auto-execute',
enforce: 'pre',
transform(code, id) {
if (id.match(/nuxt3?\/.*\/entry\./)) {
return code.replace(
/(?<!vueAppPromise = )entry\(\)\.catch/,
'Promise.resolve().catch'
)
}
},
},
nuxtRuntimeConfig: options.nuxt.options.runtimeConfig,
nuxtRouteRules: defu(
{},
options.nuxt.options.routeRules,
options.nuxt.options.nitro?.routeRules
),
},
environmentMatchGlobs: [
['**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', 'nuxt'],
['{test,tests}/nuxt/**.*', 'nuxt'],
...(options.viteConfig.test?.environmentMatchGlobs || []),
],
deps: {
...options.viteConfig.test?.deps,
inline: [
// vite-node defaults
/\/node_modules\/(.*\/)?(nuxt|nuxt3)\//,
/^#/,
// additional deps
'@nuxt/test-utils',
'vitest-environment-nuxt',
...(options.nuxt.options.build.transpile.filter(
r => typeof r === 'string' || r instanceof RegExp
) as Array<string | RegExp>),
...(typeof options.viteConfig.test?.deps?.inline !== 'boolean'
? typeof options.viteConfig.test?.deps?.inline
: []),
test: {
dir: process.cwd(),
environmentOptions: {
nuxtRuntimeConfig: options.nuxt.options.runtimeConfig,
nuxtRouteRules: defu(
{},
options.nuxt.options.routeRules,
options.nuxt.options.nitro?.routeRules
),
},
environmentMatchGlobs: [
['**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', 'nuxt'],
['{test,tests}/nuxt/**.*', 'nuxt'],
],
},
},
}
deps: {
inline: [
// vite-node defaults
/\/node_modules\/(.*\/)?(nuxt|nuxt3)\//,
/^#/,
// additional deps
'@nuxt/test-utils',
'vitest-environment-nuxt',
...(options.nuxt.options.build.transpile.filter(
r => typeof r === 'string' || r instanceof RegExp
) as Array<string | RegExp>),
...(typeof options.viteConfig.test?.deps?.inline !== 'boolean'
? typeof options.viteConfig.test?.deps?.inline
: []),
],
},
} satisfies VitestConfig,
} satisfies InlineConfig,
// resolved vite config
options.viteConfig,
// (overrideable) defaults
{
test: {
environmentOptions: {
nuxt: {
rootId: options.nuxt.options.app.rootId || undefined,
mock: {
intersectionObserver: true,
indexedDb: false,
},
}
}
} satisfies VitestConfig
}
) as InlineConfig & { test: VitestConfig }
}

export function defineVitestConfig(config: InlineConfig = {}) {
// @ts-expect-error TODO: investigate type mismatch
return defineConfig(async () => {
// When Nuxt module calls `startVitest`, we don't need to call `getVitestConfigFromNuxt` again
if (process.env.__NUXT_VITEST_RESOLVED__) return config

const overrides = config.test?.environmentOptions?.nuxt?.overrides || {}
overrides.rootDir = config.test?.environmentOptions?.nuxt?.rootDir

return mergeConfig(
return defu(
config,
await getVitestConfigFromNuxt(undefined, overrides),
config
)
})
}
Expand Down
47 changes: 17 additions & 30 deletions src/environments/vitest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,31 @@ import { createFetch } from 'ofetch'
import { indexedDB } from 'fake-indexeddb'
import { joinURL } from 'ufo'
import { createApp, defineEventHandler, toNodeListener } from 'h3'
import {
createRouter as createRadixRouter,
exportMatcher,
toRouteMatcher,
} from 'radix3'
import defu from 'defu'
import { createRouter as createRadixRouter, exportMatcher, toRouteMatcher } from 'radix3'
import { populateGlobal } from 'vitest/environments'
import {
createCall,
createFetch as createLocalFetch,
} from 'unenv/runtime/fetch/index'
import { createCall, createFetch as createLocalFetch } from 'unenv/runtime/fetch/index'

import type { NuxtBuiltinEnvironment } from './types'
import happyDom from './env/happy-dom'
import jsdom from './env/jsdom'

const environmentMap = {
'happy-dom': happyDom,
jsdom,
}

export default <Environment>{
name: 'nuxt',
async setup(global, environmentOptions) {
const url = joinURL(
'http://localhost:3000',
environmentOptions?.nuxtRuntimeConfig.app?.baseURL || '/'
)
const { window: win, teardown } = await {
'happy-dom': happyDom,
jsdom,
}[
(environmentOptions.nuxt.domEnvironment as NuxtBuiltinEnvironment) ||
'happy-dom'
](global, {
...environmentOptions,
happyDom: {
url,
...environmentOptions?.happyDom,
},
jsdom: {
url,
...environmentOptions?.jsdom,
},
})
const url = joinURL('http://localhost:3000', environmentOptions?.nuxtRuntimeConfig.app?.baseURL || '/')

const environmentName = (environmentOptions.nuxt.domEnvironment as NuxtBuiltinEnvironment)
const environment = environmentMap[environmentName] || environmentMap['happy-dom']
const { window: win, teardown } = await environment(global, defu(environmentOptions, {
happyDom: { url },
jsdom: { url },
}))

win.__NUXT__ = {
serverRendered: false,
Expand Down
9 changes: 1 addition & 8 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,7 @@ export default defineNuxtModule<NuxtVitestOptions>({
async function start() {
const rawViteConfig = mergeConfig({}, await rawViteConfigPromise)

const viteConfig = mergeConfig(
await getVitestConfigFromNuxt({ nuxt, viteConfig: rawViteConfig }),
<ViteConfig>{
server: {
middlewareMode: false,
},
}
)
const viteConfig = await getVitestConfigFromNuxt({ nuxt, viteConfig: rawViteConfig })

viteConfig.plugins = (viteConfig.plugins || []).filter((p: any) => {
return !vitePluginBlocklist.includes(p?.name)
Expand Down
Loading