Skip to content

Commit

Permalink
feat(nuxt3): remove <script setup> transform and prefer top level a…
Browse files Browse the repository at this point in the history
…wait (nuxt#579)

Co-authored-by: Pooya Parsa <pyapar@gmail.com>
  • Loading branch information
antfu and pi0 authored Sep 30, 2021
1 parent a5f446c commit e13baf9
Show file tree
Hide file tree
Showing 19 changed files with 15 additions and 221 deletions.
27 changes: 2 additions & 25 deletions docs/content/2.app/3.data-fetching.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,14 @@ asyncData(key: string, fn: () => Object, options?: { defer: boolean, server: boo

Under the hood, `defer: false` uses `<Suspense>` to block the loading of the route before the data has been fetched. Consider using `defer: true` and implementing a loading state instead for a snappier user experience.

This helper only works with:
- a component defined with `defineNuxtComponent`
- `<script setup nuxt>` syntax block

### Example

```vue
<script setup nuxt>
const { data } = asyncData('time', () => $fetch('/api/count'))
<script setup>
const { data } = await asyncData('time', () => $fetch('/api/count'))
</script>
<template>
Page visits: {{ data.count }}
</template>
```

If you don't want to use the `<script setup>` syntax, you need to use the `defineNuxtComponent` method to define your component:

```vue
<template>
Page visits: {{ data.count }}
</template>
<script>
export default defineNuxtComponent({
setup () {
const { data } = asyncData('time', () => $fetch('/api/count'))
return { data }
}
})
</script>
```


5 changes: 0 additions & 5 deletions examples/async-data-setup/nuxt.config.ts

This file was deleted.

12 changes: 0 additions & 12 deletions examples/async-data-setup/package.json

This file was deleted.

10 changes: 0 additions & 10 deletions examples/async-data-setup/pages/index.vue

This file was deleted.

3 changes: 0 additions & 3 deletions examples/async-data-setup/server/api/count.js

This file was deleted.

13 changes: 0 additions & 13 deletions examples/async-data/app.vue

This file was deleted.

1 change: 1 addition & 0 deletions examples/async-data/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineNuxtConfig } from '@nuxt/kit'

export default defineNuxtConfig({
// vite: true
})
12 changes: 2 additions & 10 deletions examples/async-data/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
</div>
</template>

<script lang="ts">
export default defineNuxtComponent({
setup () {
const { data } = asyncData('time', () => $fetch('/api/count'))
return {
data
}
}
})
<script setup>
const { data } = await asyncData('time', () => $fetch('/api/count'))
</script>
28 changes: 0 additions & 28 deletions examples/async-data/pages/options.vue

This file was deleted.

10 changes: 2 additions & 8 deletions packages/nuxt3/src/app/composables/asyncData.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { getCurrentInstance, onBeforeMount, onUnmounted, ref, unref } from 'vue'
import { onBeforeMount, onUnmounted, ref, unref } from 'vue'
import type { UnwrapRef, Ref } from 'vue'

import { NuxtComponentPendingPromises } from './component'
import { ensureReactive, useGlobalData } from './data'
import { NuxtApp, useNuxtApp } from '#app'

Expand All @@ -23,7 +22,6 @@ export type AsyncDataResult<T> = AsyncDataState<T> & Promise<AsyncDataState<T>>

export function useAsyncData (defaults?: AsyncDataOptions) {
const nuxt = useNuxtApp()
const vm = getCurrentInstance()
const onBeforeMountCbs: Array<() => void> = []

if (process.client) {
Expand Down Expand Up @@ -66,6 +64,7 @@ export function useAsyncData (defaults?: AsyncDataOptions) {
state.pending.value = true
nuxt._asyncDataPromises[key] = Promise.resolve(handler(nuxt)).then((result) => {
for (const _key in result) {
// @ts-expect-error
state.data[_key] = unref(result[_key])
}
return state.data
Expand Down Expand Up @@ -105,11 +104,6 @@ export function useAsyncData (defaults?: AsyncDataOptions) {
}
}

// Auto enqueue if within nuxt component instance
if (nuxt._asyncDataPromises[key] && vm[NuxtComponentPendingPromises]) {
vm[NuxtComponentPendingPromises].push(nuxt._asyncDataPromises[key])
}

const res = Promise.resolve(nuxt._asyncDataPromises[key]).then(() => state) as AsyncDataResult<T>
res.data = state.data
res.pending = state.pending
Expand Down
35 changes: 5 additions & 30 deletions packages/nuxt3/src/app/composables/component.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,17 @@
import { toRefs } from '@vue/reactivity'
import { defineComponent, getCurrentInstance } from 'vue'
import type { ComponentInternalInstance, DefineComponent } from 'vue'
import type { DefineComponent } from 'vue'
import { useRoute } from 'vue-router'
import type { LegacyContext } from '../legacy'
import { useNuxtApp } from '../nuxt'
import { asyncData } from './asyncData'

export const NuxtComponentIndicator = '__nuxt_component'
export const NuxtComponentPendingPromises = '_pendingPromises'

export interface NuxtComponentInternalInstance extends ComponentInternalInstance {
[NuxtComponentPendingPromises]: Array<Promise<void>>
}

export function getCurrentNuxtComponentInstance (): NuxtComponentInternalInstance {
const vm = getCurrentInstance() as NuxtComponentInternalInstance

if (!vm || !vm.proxy.$options[NuxtComponentIndicator]) {
throw new Error('This method can only be used within a component defined with `defineNuxtComponent()`.')
}

return vm
}

export function enqueueNuxtComponent (p: Promise<void>) {
const vm = getCurrentNuxtComponentInstance()
vm[NuxtComponentPendingPromises].push(p)
}

async function runLegacyAsyncData (res: Record<string, any> | Promise<Record<string, any>>, fn: (context: LegacyContext) => Promise<Record<string, any>>) {
const nuxt = useNuxtApp()
const route = useRoute()
const vm = getCurrentNuxtComponentInstance()
const vm = getCurrentInstance()
const { fetchKey } = vm.proxy.$options
const key = typeof fetchKey === 'function' ? fetchKey(() => '') : fetchKey || route.fullPath
const { data } = await asyncData(`options:asyncdata:${key}`, () => fn(nuxt._legacyContext))
Expand All @@ -42,6 +22,7 @@ export const defineNuxtComponent: typeof defineComponent =
function defineNuxtComponent (options: any): any {
const { setup } = options

// Avoid wrapping if no options api is used
if (!setup && !options.asyncData) {
return {
[NuxtComponentIndicator]: true,
Expand All @@ -53,26 +34,20 @@ export const defineNuxtComponent: typeof defineComponent =
[NuxtComponentIndicator]: true,
...options,
setup (props, ctx) {
const vm = getCurrentNuxtComponentInstance()
let promises = vm[NuxtComponentPendingPromises] = vm[NuxtComponentPendingPromises] || []

const res = setup?.(props, ctx) || {}

let promises: unknown[] | undefined = []
promises = promises || []
if (options.asyncData) {
promises.push(runLegacyAsyncData(res, options.asyncData))
}

if (!promises.length && !(res instanceof Promise)) {
return res
}

return Promise.resolve(res)
.then(() => Promise.all(promises))
.then(() => res)
.finally(() => {
promises.length = 0
promises = null
delete vm[NuxtComponentPendingPromises]
})
}
} as DefineComponent
Expand Down
4 changes: 1 addition & 3 deletions packages/vite/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import vitePlugin from '@vitejs/plugin-vue'

import { cacheDirPlugin } from './plugins/cache-dir'
import { replace } from './plugins/replace'
import { transformNuxtSetup } from './plugins/transformSetup'
import { wpfs } from './utils/wpfs'
import type { ViteBuildContext, ViteOptions } from './vite'

Expand Down Expand Up @@ -37,8 +36,7 @@ export async function buildClient (ctx: ViteBuildContext) {
plugins: [
replace({ 'process.env': 'import.meta.env' }),
cacheDirPlugin(ctx.nuxt.options.rootDir, 'client'),
vitePlugin(ctx.config.vue),
transformNuxtSetup()
vitePlugin(ctx.config.vue)
],
server: {
middlewareMode: true
Expand Down
31 changes: 0 additions & 31 deletions packages/vite/src/plugins/transformSetup.ts

This file was deleted.

4 changes: 1 addition & 3 deletions packages/vite/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import consola from 'consola'
import { ViteBuildContext, ViteOptions } from './vite'
import { wpfs } from './utils/wpfs'
import { cacheDirPlugin } from './plugins/cache-dir'
import { transformNuxtSetup } from './plugins/transformSetup'

export async function buildServer (ctx: ViteBuildContext) {
const serverConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, {
Expand Down Expand Up @@ -50,8 +49,7 @@ export async function buildServer (ctx: ViteBuildContext) {
},
plugins: [
cacheDirPlugin(ctx.nuxt.options.rootDir, 'server'),
vuePlugin(),
transformNuxtSetup()
vuePlugin()
]
} as ViteOptions)

Expand Down
3 changes: 1 addition & 2 deletions packages/webpack/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
declaration: true,
entries: [
'src/index',
'src/loaders/nuxt-setup-loader'
'src/index'
],
dependencies: [
'@nuxt/kit',
Expand Down
9 changes: 0 additions & 9 deletions packages/webpack/src/loaders/nuxt-setup-loader.ts

This file was deleted.

18 changes: 0 additions & 18 deletions packages/webpack/src/plugins/transform-setup.ts

This file was deleted.

3 changes: 0 additions & 3 deletions packages/webpack/src/presets/vue.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { resolve } from 'pathe'
import VueLoaderPlugin from 'vue-loader/dist/pluginWebpack5'
import { DefinePlugin } from 'webpack'
import NuxtSetupTransformerPlugin from '../plugins/transform-setup'
import VueSSRClientPlugin from '../plugins/vue/client'
import VueSSRServerPlugin from '../plugins/vue/server'
import { WebpackConfigContext } from '../utils/config'
Expand All @@ -27,8 +26,6 @@ export function vue (ctx: WebpackConfigContext) {
}))
}

config.plugins.push(new NuxtSetupTransformerPlugin())

// Feature flags
// https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags
// TODO: Provide options to toggle
Expand Down
8 changes: 0 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6717,14 +6717,6 @@ __metadata:
languageName: node
linkType: hard

"example-async-data-setup@workspace:examples/async-data-setup":
version: 0.0.0-use.local
resolution: "example-async-data-setup@workspace:examples/async-data-setup"
dependencies:
nuxt3: latest
languageName: unknown
linkType: soft

"example-async-data@workspace:examples/async-data":
version: 0.0.0-use.local
resolution: "example-async-data@workspace:examples/async-data"
Expand Down

0 comments on commit e13baf9

Please sign in to comment.