feat(nuxt3): create root component (#750)

This commit is contained in:
pooya parsa 2021-10-12 14:51:41 +02:00 committed by GitHub
parent b35b111032
commit 9cb9bb651e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 66 additions and 184 deletions

View File

@ -32,7 +32,7 @@ export default () => {
} }
``` ```
```vue [pages/index.vue] ```vue [app.vue]
<script setup> <script setup>
const { data } = await useAsyncData('count', () => $fetch('/api/count')) const { data } = await useAsyncData('count', () => $fetch('/api/count'))
</script> </script>
@ -68,7 +68,7 @@ Available options:
### Example ### Example
```vue [pages/index.vue] ```vue [app.vue]
<script setup> <script setup>
const { data } = await useFetch('/api/count') const { data } = await useFetch('/api/count')
</script> </script>

View File

@ -1,5 +1,5 @@
{ {
"name": "example-pages", "name": "example-use-async-data",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"nuxt3": "latest" "nuxt3": "latest"

View File

@ -1,5 +1,5 @@
{ {
"name": "example-meta", "name": "example-use-meta",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"nuxt3": "latest" "nuxt3": "latest"

View File

@ -1,12 +0,0 @@
{
"name": "example-wasm",
"private": true,
"devDependencies": {
"nuxt3": "latest"
},
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"start": "node .output/server/index.mjs"
}
}

View File

@ -1,5 +1,5 @@
{ {
"name": "example-async-data", "name": "example-with-pages",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"nuxt3": "latest" "nuxt3": "latest"

View File

@ -1,5 +0,0 @@
<template>
<div>
Hello Nuxt+Vite!
</div>
</template>

View File

@ -1,5 +0,0 @@
import { defineNuxtConfig } from 'nuxt3'
export default defineNuxtConfig({
vite: true
})

View File

@ -1,14 +0,0 @@
{
"name": "example-with-vue-content-loader",
"private": true,
"devDependencies": {
"nuxt3": "latest",
"vue": "^3",
"vue-content-loader": "^2.0.0"
},
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"start": "node .output/server/index.mjs"
}
}

View File

@ -1,76 +0,0 @@
<template>
<div class="profile">
<ContentLoader v-if="pending" width="400" height="60">
<rect
x="70"
y="15"
rx="4"
ry="4"
width="117"
height="6.4"
/>
<rect
x="70"
y="35"
rx="3"
ry="3"
width="85"
height="6.4"
/>
<circle cx="30" cy="30" r="30" />
</ContentLoader>
<div v-else>
<img :src="data.avatar" height="55" width="55">
<div>
{{ data.text }}
<br>
{{ data.text }}
</div>
</div>
</div>
</template>
<script lang="ts">
import { ContentLoader } from 'vue-content-loader'
export default defineNuxtComponent({
components: { ContentLoader },
setup () {
const { data, pending } = useAsyncData(
'time',
() =>
new Promise(resolve =>
setTimeout(
() =>
resolve({
text: 'finally done',
avatar:
'https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=256&h=256&q=80'
}),
2500
)
),
{ defer: true, server: false }
)
return {
data,
pending
}
}
})
</script>
<style>
.profile {
width: 400px;
height: 60px;
}
.profile img {
border-radius: 50%;
}
.profile > div {
display: flex;
align-items: center;
gap: 1rem;
}
</style>

View File

@ -1,5 +1,5 @@
{ {
"name": "example-with-vite", "name": "example-with-wasm",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"nuxt3": "latest" "nuxt3": "latest"

View File

@ -49,7 +49,8 @@ export interface NuxtPlugin {
} }
export interface NuxtApp { export interface NuxtApp {
main?: string mainComponent?: string
rootComponent?: string
dir: string dir: string
extensions: string[] extensions: string[]
plugins: NuxtPlugin[] plugins: NuxtPlugin[]

View File

@ -0,0 +1,5 @@
<template>
<Suspense>
<App />
</Suspense>
</template>

View File

@ -4,7 +4,9 @@ import '#build/css'
// @ts-ignore // @ts-ignore
import _plugins from '#build/plugins' import _plugins from '#build/plugins'
// @ts-ignore // @ts-ignore
import App from '#build/app' import RootComponent from '#build/root-component.mjs'
// @ts-ignore
import AppComponent from '#build/app-component.mjs'
let entry: Function let entry: Function
@ -12,7 +14,8 @@ const plugins = normalizePlugins(_plugins)
if (process.server) { if (process.server) {
entry = async function createNuxtAppServer (ssrContext: CreateOptions['ssrContext'] = {}) { entry = async function createNuxtAppServer (ssrContext: CreateOptions['ssrContext'] = {}) {
const app = createApp(App) const app = createApp(RootComponent)
app.component('App', AppComponent)
const nuxt = createNuxtApp({ app, ssrContext }) const nuxt = createNuxtApp({ app, ssrContext })
@ -35,7 +38,8 @@ if (process.client) {
entry = async function initApp () { entry = async function initApp () {
const isSSR = Boolean(window.__NUXT__?.serverRendered) const isSSR = Boolean(window.__NUXT__?.serverRendered)
const app = isSSR ? createSSRApp(App) : createApp(App) const app = isSSR ? createSSRApp(RootComponent) : createApp(RootComponent)
app.component('App', AppComponent)
const nuxt = createNuxtApp({ app }) const nuxt = createNuxtApp({ app })

View File

@ -8,10 +8,18 @@ type TemplateContext = {
app: NuxtApp; app: NuxtApp;
} }
export const appTemplate = { // TODO: Use an alias
filename: 'app.mjs', export const appComponentTemplate = {
filename: 'app-component.mjs',
getContents (ctx: TemplateContext) { getContents (ctx: TemplateContext) {
return `export { default } from '${ctx.app.main}'` return `export { default } from '${ctx.app.mainComponent}'`
}
}
// TODO: Use an alias
export const rootComponentTemplate = {
filename: 'root-component.mjs',
getContents (ctx: TemplateContext) {
return `export { default } from '${ctx.app.rootComponent}'`
} }
} }

View File

@ -59,13 +59,16 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
} }
// Resolve main (app.vue) // Resolve main (app.vue)
if (!app.main) { if (!app.mainComponent) {
app.main = tryResolvePath('~/App', resolveOptions) || tryResolvePath('~/app', resolveOptions) app.mainComponent = tryResolvePath('~/App', resolveOptions) || tryResolvePath('~/app', resolveOptions)
} }
if (!app.main) { if (!app.mainComponent) {
app.main = resolve(nuxt.options.appDir, 'components/nuxt-welcome.vue') app.mainComponent = resolve(nuxt.options.appDir, 'components/nuxt-welcome.vue')
} }
// Default root component
app.rootComponent = resolve(nuxt.options.appDir, 'components/nuxt-root.vue')
// Resolve plugins // Resolve plugins
app.plugins = [ app.plugins = [
...nuxt.options.plugins, ...nuxt.options.plugins,

View File

@ -15,7 +15,7 @@ export async function build (nuxt: Nuxt) {
nuxt.hook('builder:watch', async (event, path) => { nuxt.hook('builder:watch', async (event, path) => {
if (event !== 'change' && /app|plugins/i.test(path)) { if (event !== 'change' && /app|plugins/i.test(path)) {
if (path.match(/app/i)) { if (path.match(/app/i)) {
app.main = null app.mainComponent = null
} }
await generateApp(nuxt, app) await generateApp(nuxt, app)
} }

View File

@ -23,10 +23,12 @@ export default defineNuxtModule({
} }
}) })
// Add default layout for pages
nuxt.hook('app:resolve', (app) => { nuxt.hook('app:resolve', (app) => {
if (app.main.includes('nuxt-welcome')) { // Remove default root with Suspense
app.main = resolve(runtimeDir, 'app.vue') app.rootComponent = resolve(runtimeDir, 'root.vue')
// Add default layout for pages
if (app.mainComponent.includes('nuxt-welcome')) {
app.mainComponent = resolve(runtimeDir, 'app.vue')
} }
}) })

View File

@ -0,0 +1,3 @@
<template>
<App />
</template>

View File

@ -1,5 +1,12 @@
<template> <template>
<div> <div>
<NuxtPage /> <img src="~/assets/logo.svg">
<br>
Hello Nuxt 3
</div> </div>
</template> </template>
<script>
export default defineNuxtComponent({
})
</script>

View File

@ -1,12 +0,0 @@
<template>
<div>
<img src="~/assets/logo.svg">
<br>
Hello Nuxt 3
</div>
</template>
<script>
export default defineNuxtComponent({
})
</script>

View File

@ -9199,14 +9199,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"example-async-data@workspace:examples/async-data":
version: 0.0.0-use.local
resolution: "example-async-data@workspace:examples/async-data"
dependencies:
nuxt3: latest
languageName: unknown
linkType: soft
"example-hello-world@workspace:examples/hello-world": "example-hello-world@workspace:examples/hello-world":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "example-hello-world@workspace:examples/hello-world" resolution: "example-hello-world@workspace:examples/hello-world"
@ -9215,17 +9207,9 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"example-meta@workspace:examples/meta": "example-use-async-data@workspace:examples/use-async-data":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "example-meta@workspace:examples/meta" resolution: "example-use-async-data@workspace:examples/use-async-data"
dependencies:
nuxt3: latest
languageName: unknown
linkType: soft
"example-pages@workspace:examples/pages":
version: 0.0.0-use.local
resolution: "example-pages@workspace:examples/pages"
dependencies: dependencies:
nuxt3: latest nuxt3: latest
languageName: unknown languageName: unknown
@ -9239,17 +9223,17 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"example-use-state@workspace:examples/use-state": "example-use-meta@workspace:examples/use-meta":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "example-use-state@workspace:examples/use-state" resolution: "example-use-meta@workspace:examples/use-meta"
dependencies: dependencies:
nuxt3: latest nuxt3: latest
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"example-wasm@workspace:examples/wasm": "example-use-state@workspace:examples/use-state":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "example-wasm@workspace:examples/wasm" resolution: "example-use-state@workspace:examples/use-state"
dependencies: dependencies:
nuxt3: latest nuxt3: latest
languageName: unknown languageName: unknown
@ -9271,21 +9255,19 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"example-with-vite@workspace:examples/with-vite": "example-with-pages@workspace:examples/with-pages":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "example-with-vite@workspace:examples/with-vite" resolution: "example-with-pages@workspace:examples/with-pages"
dependencies: dependencies:
nuxt3: latest nuxt3: latest
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"example-with-vue-content-loader@workspace:examples/with-vue-content-loader": "example-with-wasm@workspace:examples/with-wasm":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "example-with-vue-content-loader@workspace:examples/with-vue-content-loader" resolution: "example-with-wasm@workspace:examples/with-wasm"
dependencies: dependencies:
nuxt3: latest nuxt3: latest
vue: ^3
vue-content-loader: ^2.0.0
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -19251,15 +19233,6 @@ fsevents@~2.3.2:
languageName: node languageName: node
linkType: hard linkType: hard
"vue-content-loader@npm:^2.0.0":
version: 2.0.0
resolution: "vue-content-loader@npm:2.0.0"
peerDependencies:
vue: ^3
checksum: 92efefe9e2aa4760a1e60ecfa2358bbc9a613f89a0e90a52cecef5a315ac247cb439d0cff58cab6891ef9fec900a9e232b96ed8d7e7dc051b00eb5f0ee0bd407
languageName: node
linkType: hard
"vue-eslint-parser@npm:^7.10.0": "vue-eslint-parser@npm:^7.10.0":
version: 7.11.0 version: 7.11.0
resolution: "vue-eslint-parser@npm:7.11.0" resolution: "vue-eslint-parser@npm:7.11.0"
@ -19405,7 +19378,7 @@ fsevents@~2.3.2:
languageName: node languageName: node
linkType: hard linkType: hard
"vue@npm:3.2.20, vue@npm:^3, vue@npm:^3.2.20": "vue@npm:3.2.20, vue@npm:^3.2.20":
version: 3.2.20 version: 3.2.20
resolution: "vue@npm:3.2.20" resolution: "vue@npm:3.2.20"
dependencies: dependencies: