import url from 'node:url'
import path from 'node:path'
import logger from '@wdio/logger'
import { resolve } from 'import-meta-resolve'
import type { InlineConfig } from 'vite'
import { hasFileByExtensions, hasDir } from '../utils.js'
declare global {
var defineNuxtConfig: Function
}
const log = logger('@wdio/browser-runner:NuxtOptimization')
export async function isNuxtFramework (rootDir: string) {
return (
await Promise.all([
hasFileByExtensions(path.join(rootDir, 'nuxt.config')),
hasDir(path.join(rootDir, '.nuxt'))
])
).filter(Boolean).length > 0
}
export async function optimizeForNuxt (options: WebdriverIO.BrowserRunnerOptions, config: WebdriverIO.Config): Promise<InlineConfig> {
const Unimport = (await import('unimport/unplugin')).default
const { scanDirExports, scanExports } = await import('unimport')
const { loadNuxtConfig } = await import('@nuxt/kit')
const rootDir = config.rootDir || process.cwd()
const nuxtOptions = await loadNuxtConfig({ rootDir })
if (nuxtOptions.imports?.autoImport === false) {
return {}
}
const nuxtDepPath = await resolve('nuxt', import.meta.url)
const composablesDirs: string[] = []
for (const layer of nuxtOptions._layers) {
composablesDirs.push(path.resolve(layer.config.srcDir, 'composables'))
composablesDirs.push(path.resolve(layer.config.srcDir, 'utils'))
for (const dir of (layer.config.imports?.dirs ?? [])) {
if (!dir) {
continue
}
composablesDirs.push(path.resolve(layer.config.srcDir, dir))
}
}
const composableImports = await Promise.all([
scanDirExports([
...composablesDirs,
path.resolve(path.dirname(url.fileURLToPath(nuxtDepPath)), 'app', 'components')
]),
scanExports(path.resolve(path.dirname(url.fileURLToPath(nuxtDepPath)), 'app', 'composables', 'index.js'))
]).then((scannedExports) => scannedExports.flat().map((ci) => {
* auto mock nuxt composables as they can't be loaded within the browser
*/
if (ci.from.includes('/nuxt/dist/app/composables')) {
ci.from = 'virtual:wdio'
ci.name = 'wrappedFn'
}
return ci
}))
const viteConfig: InlineConfig = {
resolve: {
alias: nuxtOptions.alias || {}
},
plugins: [Unimport.vite({
presets: ['vue'],
imports: composableImports
})]
}
log.info(`Optimized Vite config for Nuxt project at ${rootDir}`)
return viteConfig
}