mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 21:25:11 +00:00
test(nuxt): add test suite for app resolution behaviour (#23520)
This commit is contained in:
parent
93ace55481
commit
5397e93ff0
@ -79,7 +79,8 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?:
|
||||
await nuxt.callHook('app:templatesGenerated', app, filteredTemplates, options)
|
||||
}
|
||||
|
||||
async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
||||
/** @internal */
|
||||
export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
||||
// Resolve main (app.vue)
|
||||
if (!app.mainComponent) {
|
||||
app.mainComponent = await findPath(
|
||||
|
221
packages/nuxt/test/app.test.ts
Normal file
221
packages/nuxt/test/app.test.ts
Normal file
@ -0,0 +1,221 @@
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { mkdir, rm, writeFile } from 'node:fs/promises'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { afterAll, describe, expect, it } from 'vitest'
|
||||
import { dirname, join, normalize, resolve } from 'pathe'
|
||||
import { withoutTrailingSlash } from 'ufo'
|
||||
import { createApp, resolveApp } from '../src/core/app'
|
||||
import { loadNuxt } from '../src'
|
||||
|
||||
const repoRoot = withoutTrailingSlash(normalize(fileURLToPath(new URL('../../../', import.meta.url))))
|
||||
|
||||
describe('resolveApp', () => {
|
||||
afterAll(async () => {
|
||||
await rm(resolve(repoRoot, '.fixture'), { recursive: true, force: true })
|
||||
})
|
||||
it('resolves app with default configuration', async () => {
|
||||
const app = await getResolvedApp([])
|
||||
expect(app).toMatchInlineSnapshot(`
|
||||
{
|
||||
"components": [],
|
||||
"configs": [],
|
||||
"dir": "<rootDir>",
|
||||
"errorComponent": "<repoRoot>/packages/nuxt/src/app/components/nuxt-error-page.vue",
|
||||
"extensions": [
|
||||
".js",
|
||||
".jsx",
|
||||
".mjs",
|
||||
".ts",
|
||||
".tsx",
|
||||
".vue",
|
||||
],
|
||||
"layouts": {},
|
||||
"mainComponent": "@nuxt/ui-templates/dist/templates/welcome.vue",
|
||||
"middleware": [
|
||||
{
|
||||
"global": true,
|
||||
"name": "manifest-route-rule",
|
||||
"path": "<repoRoot>/packages/nuxt/src/app/middleware/manifest-route-rule.ts",
|
||||
},
|
||||
],
|
||||
"plugins": [
|
||||
{
|
||||
"mode": "client",
|
||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/payload.client.ts",
|
||||
},
|
||||
{
|
||||
"mode": "server",
|
||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/revive-payload.server.ts",
|
||||
},
|
||||
{
|
||||
"mode": "client",
|
||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/revive-payload.client.ts",
|
||||
},
|
||||
{
|
||||
"filename": "components.plugin.mjs",
|
||||
"getContents": [Function],
|
||||
"mode": "all",
|
||||
"src": "<rootDir>/.nuxt/components.plugin.mjs",
|
||||
},
|
||||
{
|
||||
"mode": "all",
|
||||
"src": "<repoRoot>/packages/nuxt/src/head/runtime/plugins/unhead.ts",
|
||||
},
|
||||
{
|
||||
"mode": "all",
|
||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/router.ts",
|
||||
},
|
||||
{
|
||||
"mode": "client",
|
||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/chunk-reload.client.ts",
|
||||
},
|
||||
{
|
||||
"mode": "client",
|
||||
"src": "<repoRoot>/packages/nuxt/src/app/plugins/check-outdated-build.client.ts",
|
||||
},
|
||||
],
|
||||
"rootComponent": "<repoRoot>/packages/nuxt/src/app/components/nuxt-root.vue",
|
||||
"templates": [],
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
it('resolves layer plugins in correct order', async () => {
|
||||
const app = await getResolvedApp([
|
||||
// layer 1
|
||||
'layer1/plugins/02.plugin.ts',
|
||||
'layer1/plugins/object-named.ts',
|
||||
'layer1/plugins/override-test.ts',
|
||||
'layer1/nuxt.config.ts',
|
||||
// layer 2
|
||||
'layer2/plugins/01.plugin.ts',
|
||||
'layer2/plugins/object-named.ts',
|
||||
'layer2/plugins/override-test.ts',
|
||||
'layer2/nuxt.config.ts',
|
||||
// final (user) layer
|
||||
'plugins/00.plugin.ts',
|
||||
'plugins/object-named.ts',
|
||||
{
|
||||
name: 'nuxt.config.ts',
|
||||
contents: 'export default defineNuxtConfig({ extends: [\'./layer2\', \'./layer1\'] })'
|
||||
}
|
||||
])
|
||||
const fixturePlugins = app.plugins.filter(p => !('getContents' in p) && p.src.includes('<rootDir>')).map(p => p.src)
|
||||
// TODO: support overriding named plugins
|
||||
expect(fixturePlugins).toMatchInlineSnapshot(`
|
||||
[
|
||||
"<rootDir>/layer1/plugins/02.plugin.ts",
|
||||
"<rootDir>/layer1/plugins/object-named.ts",
|
||||
"<rootDir>/layer1/plugins/override-test.ts",
|
||||
"<rootDir>/layer2/plugins/01.plugin.ts",
|
||||
"<rootDir>/layer2/plugins/object-named.ts",
|
||||
"<rootDir>/layer2/plugins/override-test.ts",
|
||||
"<rootDir>/plugins/00.plugin.ts",
|
||||
"<rootDir>/plugins/object-named.ts",
|
||||
]
|
||||
`)
|
||||
})
|
||||
|
||||
it('resolves layer middleware in correct order', async () => {
|
||||
const app = await getResolvedApp([
|
||||
// layer 1
|
||||
'layer1/middleware/global.global.ts',
|
||||
'layer1/middleware/named-from-layer.ts',
|
||||
'layer1/middleware/named-override.ts',
|
||||
'layer1/nuxt.config.ts',
|
||||
// layer 2
|
||||
'layer2/middleware/global.global.ts',
|
||||
'layer2/middleware/named-from-layer.ts',
|
||||
'layer2/middleware/named-override.ts',
|
||||
'layer2/plugins/override-test.ts',
|
||||
'layer2/nuxt.config.ts',
|
||||
// final (user) layer
|
||||
'middleware/named-override.ts',
|
||||
'middleware/named.ts',
|
||||
{
|
||||
name: 'nuxt.config.ts',
|
||||
contents: 'export default defineNuxtConfig({ extends: [\'./layer2\', \'./layer1\'] })'
|
||||
}
|
||||
])
|
||||
const fixtureMiddleware = app.middleware.filter(p => p.path.includes('<rootDir>')).map(p => p.path)
|
||||
// TODO: fix this
|
||||
expect(fixtureMiddleware).toMatchInlineSnapshot(`
|
||||
[
|
||||
"<rootDir>/layer1/middleware/global.global.ts",
|
||||
"<rootDir>/layer1/middleware/named-from-layer.ts",
|
||||
"<rootDir>/layer1/middleware/named-override.ts",
|
||||
"<rootDir>/middleware/named.ts",
|
||||
]
|
||||
`)
|
||||
})
|
||||
|
||||
it('resolves layer layouts correctly', async () => {
|
||||
const app = await getResolvedApp([
|
||||
// layer 1
|
||||
'layer1/layouts/default.vue',
|
||||
'layer1/layouts/layer.vue',
|
||||
'layer1/nuxt.config.ts',
|
||||
// layer 2
|
||||
'layer2/layouts/default.vue',
|
||||
'layer2/layouts/layer.vue',
|
||||
'layer2/nuxt.config.ts',
|
||||
// final (user) layer
|
||||
'layouts/default.vue',
|
||||
{
|
||||
name: 'nuxt.config.ts',
|
||||
contents: 'export default defineNuxtConfig({ extends: [\'./layer2\', \'./layer1\'] })'
|
||||
}
|
||||
])
|
||||
expect(app.layouts).toMatchInlineSnapshot(`
|
||||
{
|
||||
"default": {
|
||||
"file": "<rootDir>/layouts/default.vue",
|
||||
"name": "default",
|
||||
},
|
||||
"layer": {
|
||||
"file": "<rootDir>/layer2/layouts/layer.vue",
|
||||
"name": "layer",
|
||||
},
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
async function getResolvedApp (files: Array<string | { name: string, contents: string }>) {
|
||||
const rootDir = resolve(repoRoot, 'node_modules/.fixture', randomUUID())
|
||||
await mkdir(rootDir, { recursive: true })
|
||||
for (const file of files) {
|
||||
const filename = typeof file === 'string' ? join(rootDir, file) : join(rootDir, file.name)
|
||||
await mkdir(dirname(filename), { recursive: true })
|
||||
await writeFile(filename, typeof file === 'string' ? '' : file.contents || '')
|
||||
}
|
||||
|
||||
const nuxt = await loadNuxt({ cwd: rootDir })
|
||||
const app = createApp(nuxt)
|
||||
await resolveApp(nuxt, app)
|
||||
|
||||
const normaliseToRepo = (id?: string | null) =>
|
||||
id?.replace(rootDir, '<rootDir>').replace(repoRoot, '<repoRoot>').replace(/.*node_modules\//, '')
|
||||
|
||||
app.dir = normaliseToRepo(app.dir)!
|
||||
|
||||
const componentKeys = ['rootComponent', 'errorComponent', 'mainComponent'] as const
|
||||
for (const _key of componentKeys) {
|
||||
const key = _key as typeof componentKeys[number]
|
||||
app[key] = normaliseToRepo(app[key])
|
||||
}
|
||||
for (const plugin of app.plugins) {
|
||||
plugin.src = normaliseToRepo(plugin.src)!
|
||||
}
|
||||
for (const mw of app.middleware) {
|
||||
mw.path = normaliseToRepo(mw.path)!
|
||||
}
|
||||
|
||||
for (const layout in app.layouts) {
|
||||
app.layouts[layout].file = normaliseToRepo(app.layouts[layout].file)!
|
||||
}
|
||||
|
||||
await nuxt.close()
|
||||
|
||||
return app
|
||||
}
|
Loading…
Reference in New Issue
Block a user