feat: preliminary vue-app types

This commit is contained in:
Daniel Roe 2020-07-30 00:45:48 +01:00
parent e7dd27fa2a
commit 426cf1b3de
11 changed files with 84 additions and 13 deletions

View File

@ -0,0 +1,10 @@
declare module NodeJS {
interface Process {
browser: boolean
client: boolean
mode: 'spa' | 'universal'
modern: boolean
server: boolean
static: boolean
}
}

View File

@ -0,0 +1,6 @@
declare module 'nuxt-build/routes' {
import { RouteRecordRaw } from 'vue-router'
const _default: RouteRecordRaw[]
export default _default
}

View File

@ -0,0 +1,3 @@
interface Window {
__NUXT__?: Record<string, any>
}

View File

@ -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<Element>
ssrContext?: Record<string, any>
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
}
}

View File

@ -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

View File

@ -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<Element> & { $root?: App<Element> } = { ...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

View File

@ -1,9 +1,13 @@
export default function preload ({ app }) {
import type { Plugin } from 'nuxt/vue-app/types'
const preload: Plugin = function ({ app }) {
app.mixin({
beforeCreate () {
beforeCreate() {
const { _registeredComponents } = this.$nuxt.ssrContext
const { __moduleIdentifier } = this.$options
_registeredComponents.push(__moduleIdentifier)
}
})
}
export default preload

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
import type { Nuxt } from './nuxt';
export interface Plugin {
(nuxt: Nuxt, inject?: Nuxt['provide']): Promise<void> | void
}

View File

@ -1,3 +1,3 @@
export function defineGetter (obj, key, val) {
export function defineGetter<K extends string | number | symbol, V> (obj: Record<K, V>, key: K, val: V) {
Object.defineProperty(obj, key, { get: () => val })
}