diff --git a/packages/kit/build.config.ts b/packages/kit/build.config.ts index 84d8be078c..cb563b1e0a 100644 --- a/packages/kit/build.config.ts +++ b/packages/kit/build.config.ts @@ -12,5 +12,6 @@ export default { } }, 'src/index' - ] + ], + externals: ['webpack'] } diff --git a/packages/kit/src/types/hooks.ts b/packages/kit/src/types/hooks.ts index 654114eed6..3680a2999f 100644 --- a/packages/kit/src/types/hooks.ts +++ b/packages/kit/src/types/hooks.ts @@ -1,13 +1,118 @@ +import type { IncomingMessage, ServerResponse } from 'http' +import type { Compiler, Configuration, Stats } from 'webpack' +import type { NuxtConfig, NuxtOptions } from '..' +import type { ModuleContainer } from '../module/container' + import { Nuxt } from './nuxt' -export type NuxtHook = (arg1?: Arg1, ...args: any) => Promise | void +type HookResult = Promise | void + +type Builder = any +type Generator = any +type Server = any + +type TemplateFile = string | { + src?: string + dst?: string + custom?: boolean + options?: any +} + +type WatchEvent = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir' export interface NuxtHooks { - [key: string]: NuxtHook + // Don't break usage of untyped hooks + [key: string]: (...args: any[]) => HookResult - 'modules:before': NuxtHook - 'modules:done': NuxtHook - 'ready': NuxtHook + // @nuxt/builder + 'build:before': + (builder: Builder, buildOptions: NuxtOptions['build']) => HookResult + 'builder:prepared': (builder: Builder, buildOptions: NuxtOptions['build']) => HookResult + 'builder:extendPlugins': (plugins: NuxtOptions['plugins']) => HookResult + 'build:templates': (templates: { + templateVars: Record, + templatesFiles: TemplateFile[], + resolve: (...args: string[]) => string + }) => HookResult + 'build:extendRoutes': (routes: any[], resolve: (...args: string[]) => string) => HookResult + 'build:done': (builder: Builder) => HookResult + 'watch:restart': (event: { event: string, path: string }) => HookResult + // 'watch:fileChanged': (builder: Builder, fileName: string) => HookResult + 'builder:watch': (event: WatchEvent, path: string) => HookResult + + // @nuxt/cli + 'cli:buildError': (error: unknown) => HookResult + 'generate:cache:ignore': (ignore: string[]) => HookResult + 'config': (options: NuxtConfig) => HookResult + 'run:before': (options: { argv: string[], cmd: { name: string, usage: string, description: string, options: Record }, rootDir: string }) => HookResult + + // @nuxt/core + 'ready': (nuxt: Nuxt) => HookResult + 'close': (nuxt: Nuxt) => HookResult + 'modules:before': (moduleContainer: ModuleContainer, modules?: any[]) => HookResult + 'modules:done': (moduleContainer: ModuleContainer) => HookResult + // 'webpack:done': () => HookResult + + // @nuxt/server + 'render:before': (server: Server, renderOptions: NuxtOptions['render']) => HookResult + 'render:setupMiddleware': (app: any) => HookResult + 'render:errorMiddleware': (app: any) => HookResult + 'render:done': (server: Server) => HookResult + 'listen': (listenerServer: any, listener: any) => HookResult + 'server:nuxt:renderLoading': (req: IncomingMessage, res: ServerResponse) => HookResult + 'render:route': (url: string, result: string, context: any) => HookResult + 'render:routeDone': (url: string, result: string, context: any) => HookResult + 'render:beforeResponse': (url: string, result: string, context: any) => HookResult + + // @nuxt/vue-renderer + 'render:resourcesLoaded': (resources: any) => HookResult + 'vue-renderer:context': (renderContext: any) => HookResult + 'vue-renderer:spa:prepareContext': (renderContext: any) => HookResult + 'vue-renderer:spa:templateParams': (templateParams: Record) => HookResult + 'vue-renderer:ssr:prepareContext': (renderContext: any) => HookResult + 'vue-renderer:ssr:context': (renderContext: any) => HookResult + // '_render:context': (nuxt: Nuxt) => HookResult + // 'render:routeContext': (renderContext: any) => HookResult + 'vue-renderer:ssr:csp': (cspScriptSrcHashes: string[]) => HookResult + 'vue-renderer:ssr:templateParams': (templateParams: Record, renderContext: any) => HookResult + + // @nuxt/webpack + 'webpack:config': (webpackConfigs: Configuration[]) => HookResult + 'build:compile': (options: { name: string, compiler: Compiler }) => HookResult + 'build:compiled': (options: { name: string, compiler: Compiler, stats: Stats }) => HookResult + 'build:resources': (mfs?: Compiler['outputFileSystem']) => HookResult + 'server:devMiddleware': (middleware: (req: IncomingMessage, res: ServerResponse, next: (err?: any) => any) => any) => HookResult + 'bundler:change': (shortPath: string) => void + 'bundler:error': () => void + 'bundler:done': () => void + 'bundler:progress': (statesArray: any[]) => void + + // @nuxt/generator + 'generate:before': (generator: Generator, generateOptions: NuxtOptions['generate']) => HookResult + 'generate:distRemoved': (generator: Generator) => HookResult + 'generate:distCopied': (generator: Generator) => HookResult + 'generate:route': ({ route, setPayload }: { route: any, setPayload: any }) => HookResult + 'generate:page': (page: { + route: any, + path: string, + html: string, + exclude: boolean, + errors: string[] + }) => HookResult + 'generate:routeCreated': ({ route, path, errors }: { route: any, path: string, errors: any[] }) => HookResult + 'generate:extendRoutes': (routes: any[]) => HookResult + 'generate:routeFailed': ({ route, errors }: { route: any, errors: any[] }) => HookResult + 'generate:manifest': (manifest: any, generator: Generator) => HookResult + 'generate:done': (generator: Generator, errors: any[]) => HookResult + + 'export:before': (generator: Generator) => HookResult + 'export:distRemoved': (generator: Generator) => HookResult + 'export:distCopied': (generator: Generator) => HookResult + 'export:route': ({ route, setPayload }: { route: any, setPayload: any }) => HookResult + 'export:routeCreated': ({ route, path, errors }: { route: any, path: string, errors: any[] }) => HookResult + 'export:extendRoutes': ({ routes }: { routes: any[] }) => HookResult + 'export:routeFailed': ({ route, errors }: { route: any, errors: any[] }) => HookResult + 'export:done': (generator: Generator, { errors }: { errors: any[] }) => HookResult } export type NuxtHookName = keyof NuxtHooks diff --git a/packages/kit/src/types/nuxt.ts b/packages/kit/src/types/nuxt.ts index ff637e3d21..f32ec1bfca 100644 --- a/packages/kit/src/types/nuxt.ts +++ b/packages/kit/src/types/nuxt.ts @@ -1,13 +1,13 @@ -import { NuxtHookName, NuxtHook, NuxtHooks } from './hooks' +import { NuxtHookName, NuxtHooks } from './hooks' import { NuxtOptions } from './config' export interface Nuxt { options: NuxtOptions hooks: { - hook(hookName: NuxtHookName, callback: NuxtHook) - callHook(hookbname: T, ...args: Parameters) - addHooks(hooks: Partial) + hook(hookName: Hook, callback: NuxtHooks[Hook]): void | Promise + callHook(hookName: Hook, ...args: Parameters): ReturnType + addHooks(hooks: Partial): void } hook: Nuxt['hooks']['hook'] callHook: Nuxt['hooks']['callHook'] diff --git a/packages/nuxt3/src/nuxt.ts b/packages/nuxt3/src/nuxt.ts index 1beeba7209..576f4692bd 100644 --- a/packages/nuxt3/src/nuxt.ts +++ b/packages/nuxt3/src/nuxt.ts @@ -3,7 +3,7 @@ import { loadNuxtConfig, LoadNuxtConfigOptions, Nuxt, NuxtOptions, installModule import { initNitro } from './nitro' export function createNuxt (options: NuxtOptions): Nuxt { - const hooks = new Hookable() + const hooks = new Hookable() as any as Nuxt['hooks'] return { options, diff --git a/packages/webpack/package.json b/packages/webpack/package.json index a4ff855a3f..5b3d0c819f 100644 --- a/packages/webpack/package.json +++ b/packages/webpack/package.json @@ -46,6 +46,7 @@ "webpackbar": "^5.0.0-3" }, "devDependencies": { + "@types/pify": "^5.0.0", "@types/terser-webpack-plugin": "^5.0.3", "@types/webpack-bundle-analyzer": "^3.9.2", "@types/webpack-dev-middleware": "^4.1.2", diff --git a/packages/webpack/src/webpack.ts b/packages/webpack/src/webpack.ts index 736a3e2884..bc9062e014 100644 --- a/packages/webpack/src/webpack.ts +++ b/packages/webpack/src/webpack.ts @@ -1,4 +1,5 @@ import path from 'path' +import type { IncomingMessage, ServerResponse } from 'http' import pify from 'pify' import webpack from 'webpack' import Glob from 'glob' @@ -22,12 +23,12 @@ class WebpackBundler { compilers: Array compilersWatching: Array void }> // TODO: change this when pify has better types https://github.com/sindresorhus/pify/pull/76 - devMiddleware: Record void, context?: WebpackDevMiddlewareContext }> + devMiddleware: Record Promise, context?: WebpackDevMiddlewareContext }> hotMiddleware: Record - mfs: Compiler['outputFileSystem'] - __closed: boolean + mfs?: Compiler['outputFileSystem'] + __closed?: boolean - constructor (nuxt) { + constructor (nuxt: Nuxt) { this.nuxt = nuxt // TODO: plugins this.plugins = [] @@ -98,7 +99,7 @@ class WebpackBundler { // In dev, write files in memory FS if (options.dev) { - compiler.outputFileSystem = this.mfs + compiler.outputFileSystem = this.mfs! } return compiler @@ -175,7 +176,7 @@ class WebpackBundler { await this.nuxt.callHook('build:resources') } - async webpackDev (compiler) { + async webpackDev (compiler: Compiler) { consola.debug('Creating webpack middleware...') const { name } = compiler.options @@ -216,7 +217,7 @@ class WebpackBundler { await this.nuxt.callHook('server:devMiddleware', this.middleware) } - async middleware (req, res, next) { + async middleware (req: IncomingMessage, res: ServerResponse, next: () => any) { if (this.devMiddleware && this.devMiddleware.client) { await this.devMiddleware.client(req, res) } diff --git a/yarn.lock b/yarn.lock index 80c449e755..259e74837d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1751,6 +1751,7 @@ __metadata: "@babel/core": ^7.13.15 "@nuxt/friendly-errors-webpack-plugin": ^2.5.1 "@nuxt/kit": ^0.3.0 + "@types/pify": ^5.0.0 "@types/terser-webpack-plugin": ^5.0.3 "@types/webpack-bundle-analyzer": ^3.9.2 "@types/webpack-dev-middleware": ^4.1.2 @@ -2370,6 +2371,13 @@ __metadata: languageName: node linkType: hard +"@types/pify@npm:^5.0.0": + version: 5.0.0 + resolution: "@types/pify@npm:5.0.0" + checksum: 3e2a1ba34accea3379dfa4750dc5a5eb37e5254aa77cce22ce48f96ef87ee248519bbec684c341afe9db17f4829d44e0cdaf05f87738230602241192c2264f1b + languageName: node + linkType: hard + "@types/prettier@npm:^2.0.0": version: 2.2.3 resolution: "@types/prettier@npm:2.2.3"