From a74b48c648d2dc55adc5d47989ffdca8941e0483 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 30 Jul 2020 12:36:25 +0100 Subject: [PATCH] feat: add vue-app types (#12) * feat: preliminary vue-app types * style: fix various lint issues * style: further fixing (not caught by eslint) * chore: add alias for nuxt-app Co-authored-by: pooya parsa --- .../nuxt3/src/vue-app/declarations/node.d.ts | 10 ++++++ .../src/vue-app/declarations/nuxt-build.d.ts | 6 ++++ .../src/vue-app/declarations/window.d.ts | 3 ++ packages/nuxt3/src/vue-app/nuxt.ts | 36 ++++++++++++++++--- .../nuxt3/src/vue-app/nuxt/entry.client.ts | 2 +- .../nuxt3/src/vue-app/nuxt/plugins.server.ts | 2 +- .../nuxt3/src/vue-app/plugins/components.ts | 6 +++- packages/nuxt3/src/vue-app/plugins/legacy.ts | 9 +++-- packages/nuxt3/src/vue-app/plugins/preload.ts | 6 +++- packages/nuxt3/src/vue-app/plugins/router.ts | 6 +++- packages/nuxt3/src/vue-app/plugins/state.ts | 6 +++- packages/nuxt3/src/vue-app/types.ts | 5 +++ packages/nuxt3/src/vue-app/utils.ts | 2 +- 13 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 packages/nuxt3/src/vue-app/declarations/node.d.ts create mode 100644 packages/nuxt3/src/vue-app/declarations/nuxt-build.d.ts create mode 100644 packages/nuxt3/src/vue-app/declarations/window.d.ts create mode 100644 packages/nuxt3/src/vue-app/types.ts diff --git a/packages/nuxt3/src/vue-app/declarations/node.d.ts b/packages/nuxt3/src/vue-app/declarations/node.d.ts new file mode 100644 index 0000000000..52ed3cb71b --- /dev/null +++ b/packages/nuxt3/src/vue-app/declarations/node.d.ts @@ -0,0 +1,10 @@ +declare module NodeJS { + interface Process { + browser: boolean + client: boolean + mode: 'spa' | 'universal' + modern: boolean + server: boolean + static: boolean + } +} diff --git a/packages/nuxt3/src/vue-app/declarations/nuxt-build.d.ts b/packages/nuxt3/src/vue-app/declarations/nuxt-build.d.ts new file mode 100644 index 0000000000..f9e2263e8d --- /dev/null +++ b/packages/nuxt3/src/vue-app/declarations/nuxt-build.d.ts @@ -0,0 +1,6 @@ +declare module 'nuxt-build/routes' { + import { RouteRecordRaw } from 'vue-router' + + const _default: RouteRecordRaw[] + export default _default +} diff --git a/packages/nuxt3/src/vue-app/declarations/window.d.ts b/packages/nuxt3/src/vue-app/declarations/window.d.ts new file mode 100644 index 0000000000..cbcfb2f26d --- /dev/null +++ b/packages/nuxt3/src/vue-app/declarations/window.d.ts @@ -0,0 +1,3 @@ +interface Window { + __NUXT__?: Record +} diff --git a/packages/nuxt3/src/vue-app/nuxt.ts b/packages/nuxt3/src/vue-app/nuxt.ts index 6acf9417f6..c3e10e524d 100644 --- a/packages/nuxt3/src/vue-app/nuxt.ts +++ b/packages/nuxt3/src/vue-app/nuxt.ts @@ -1,28 +1,54 @@ +import type { IncomingMessage, ServerResponse } from 'http' import Hookable from 'hookable' +import type { App } from 'vue' + +import type { Plugin } from './types' import { defineGetter } from './utils' -class Nuxt extends Hookable { - constructor ({ app, ssrContext, globalName }) { +export class Nuxt extends Hookable { + app: App + ssrContext?: Record + globalName: string + context: { + req?: IncomingMessage + res?: ServerResponse + } + + constructor ({ app, ssrContext, globalName }: { app: Nuxt['app'], ssrContext?: Nuxt['ssrContext'], globalName: Nuxt['globalName'] }) { super() this.app = app this.ssrContext = ssrContext this.globalName = globalName } - provide (name, value) { + provide (name: string, value: any) { const $name = '$' + name defineGetter(this.app, $name, value) defineGetter(this.app.config.globalProperties, $name, value) } } -export async function init ({ app, plugins, ssrContext, globalName = 'nuxt' }) { +interface InitOptions { + app: Nuxt['app'] + plugins?: Plugin[] + ssrContext?: Nuxt['ssrContext'] + globalName?: Nuxt['globalName'] +} + +export async function init ({ app, plugins, ssrContext, globalName = 'nuxt' }: InitOptions) { const nuxt = new Nuxt({ app, ssrContext, globalName }) nuxt.provide('nuxt', nuxt) - const inject = nuxt.provide.bind(nuxt) + const inject: Nuxt['provide'] = nuxt.provide.bind(nuxt) for (const plugin of plugins) { await plugin(nuxt, inject) } } + + +declare module 'vue' { + interface App { + $nuxt: Nuxt + } +} diff --git a/packages/nuxt3/src/vue-app/nuxt/entry.client.ts b/packages/nuxt3/src/vue-app/nuxt/entry.client.ts index 0c79142316..28b5b41c5f 100644 --- a/packages/nuxt3/src/vue-app/nuxt/entry.client.ts +++ b/packages/nuxt3/src/vue-app/nuxt/entry.client.ts @@ -1,6 +1,6 @@ import { createSSRApp } from 'vue' -import plugins from './plugins.client' import { init } from 'nuxt-app' +import plugins from './plugins.client' import App from '<%= appPath %>' async function initApp () { diff --git a/packages/nuxt3/src/vue-app/nuxt/plugins.server.ts b/packages/nuxt3/src/vue-app/nuxt/plugins.server.ts index b97c807020..19fa11178e 100644 --- a/packages/nuxt3/src/vue-app/nuxt/plugins.server.ts +++ b/packages/nuxt3/src/vue-app/nuxt/plugins.server.ts @@ -1,5 +1,5 @@ -import sharedPlugins from './plugins' import preload from 'nuxt-app/plugins/preload' +import sharedPlugins from './plugins' export default [ ...sharedPlugins, diff --git a/packages/nuxt3/src/vue-app/plugins/components.ts b/packages/nuxt3/src/vue-app/plugins/components.ts index 91e5c1ee8a..96c298c6d8 100644 --- a/packages/nuxt3/src/vue-app/plugins/components.ts +++ b/packages/nuxt3/src/vue-app/plugins/components.ts @@ -1,3 +1,5 @@ +import type { Plugin } from 'nuxt/vue-app/types' + // import { h, defineComponent } from 'vue' import { RouterLink } from 'vue-router' @@ -5,7 +7,9 @@ import { RouterLink } from 'vue-router' // extends: Link // }) -export default function components ({ app }) { +const components: Plugin = function ({ app }) { app.component('NuxtLink', RouterLink) app.component('NLink', RouterLink) // TODO: deprecate } + +export default components diff --git a/packages/nuxt3/src/vue-app/plugins/legacy.ts b/packages/nuxt3/src/vue-app/plugins/legacy.ts index 5700cb818d..f32372be32 100644 --- a/packages/nuxt3/src/vue-app/plugins/legacy.ts +++ b/packages/nuxt3/src/vue-app/plugins/legacy.ts @@ -1,8 +1,11 @@ -export default function legacy ({ app }) { +import type { App } from 'vue' +import type { Plugin } from 'nuxt/vue-app/types' + +const legacy: Plugin = function ({ app }) { app.$nuxt.context = {} if (process.client) { - const legacyApp = { ...app } + const legacyApp: App & { $root?: App } = { ...app } legacyApp.$root = legacyApp window[app.$nuxt.globalName] = legacyApp } @@ -13,3 +16,5 @@ export default function legacy ({ app }) { app.$nuxt.context.res = ssrContext.res } } + +export default legacy diff --git a/packages/nuxt3/src/vue-app/plugins/preload.ts b/packages/nuxt3/src/vue-app/plugins/preload.ts index 4c3b658107..30ea61c9a4 100644 --- a/packages/nuxt3/src/vue-app/plugins/preload.ts +++ b/packages/nuxt3/src/vue-app/plugins/preload.ts @@ -1,4 +1,6 @@ -export default function preload ({ app }) { +import type { Plugin } from 'nuxt/vue-app/types' + +const preload: Plugin = function ({ app }) { app.mixin({ beforeCreate () { const { _registeredComponents } = this.$nuxt.ssrContext @@ -7,3 +9,5 @@ export default function preload ({ app }) { } }) } + +export default preload diff --git a/packages/nuxt3/src/vue-app/plugins/router.ts b/packages/nuxt3/src/vue-app/plugins/router.ts index 0aaeb769d9..b8104d28a1 100644 --- a/packages/nuxt3/src/vue-app/plugins/router.ts +++ b/packages/nuxt3/src/vue-app/plugins/router.ts @@ -1,9 +1,11 @@ import { ref } from 'vue' import { createRouter, createWebHistory, createMemoryHistory } from 'vue-router' +import type { Plugin } from 'nuxt/vue-app/types' + import routes from 'nuxt-build/routes' -export default function router ({ app }) { +const router: Plugin = function ({ app }) { const routerHistory = process.client ? createWebHistory() : createMemoryHistory() @@ -35,3 +37,5 @@ export default function router ({ app }) { }) } } + +export default router diff --git a/packages/nuxt3/src/vue-app/plugins/state.ts b/packages/nuxt3/src/vue-app/plugins/state.ts index be0a83f561..de1d20da20 100644 --- a/packages/nuxt3/src/vue-app/plugins/state.ts +++ b/packages/nuxt3/src/vue-app/plugins/state.ts @@ -1,4 +1,6 @@ -export default function state ({ app }) { +import type { Plugin } from 'nuxt/vue-app/types' + +const state: Plugin = function ({ app }) { if (process.server) { app.$nuxt.state = { serverRendered: true @@ -11,3 +13,5 @@ export default function state ({ app }) { app.$nuxt.state = window.__NUXT__ || {} } } + +export default state diff --git a/packages/nuxt3/src/vue-app/types.ts b/packages/nuxt3/src/vue-app/types.ts new file mode 100644 index 0000000000..d61c923768 --- /dev/null +++ b/packages/nuxt3/src/vue-app/types.ts @@ -0,0 +1,5 @@ +import type { Nuxt } from './nuxt'; + +export interface Plugin { + (nuxt: Nuxt, inject?: Nuxt['provide']): Promise | void +} diff --git a/packages/nuxt3/src/vue-app/utils.ts b/packages/nuxt3/src/vue-app/utils.ts index 8286417024..51fed88a2c 100644 --- a/packages/nuxt3/src/vue-app/utils.ts +++ b/packages/nuxt3/src/vue-app/utils.ts @@ -1,3 +1,3 @@ -export function defineGetter (obj, key, val) { +export function defineGetter (obj: Record, key: K, val: V) { Object.defineProperty(obj, key, { get: () => val }) }