Skip to content

Commit

Permalink
feat: use preview server parameter in preview server hook (#11647)
Browse files Browse the repository at this point in the history
  • Loading branch information
erxclau authored Mar 25, 2023
1 parent 54b376f commit 4c142ea
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 22 deletions.
40 changes: 40 additions & 0 deletions docs/guide/api-javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,46 @@ import { preview } from 'vite'
})()
```

## `PreviewServer`

```ts
interface PreviewServer extends PreviewServerForHook {
resolvedUrls: ResolvedServerUrls
}
```

## `PreviewServerForHook`

```ts
interface PreviewServerForHook {
/**
* The resolved vite config object
*/
config: ResolvedConfig
/**
* A connect app instance.
* - Can be used to attach custom middlewares to the preview server.
* - Can also be used as the handler function of a custom http server
* or as a middleware in any connect-style Node.js frameworks
*
* https://github.com/senchalabs/connect#use-middleware
*/
middlewares: Connect.Server
/**
* native Node http server instance
*/
httpServer: http.Server
/**
* The resolved urls Vite prints on the CLI
*/
resolvedUrls: ResolvedServerUrls | null
/**
* Print server urls
*/
printUrls(): void
}
```

## `resolveConfig`

**Type Signature:**
Expand Down
5 changes: 3 additions & 2 deletions docs/guide/api-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,11 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo

### `configurePreviewServer`

- **Type:** `(server: { middlewares: Connect.Server, httpServer: http.Server }) => (() => void) | void | Promise<(() => void) | void>`
- **Type:** `(server: PreviewServerForHook) => (() => void) | void | Promise<(() => void) | void>`
- **Kind:** `async`, `sequential`
- **See also:** [PreviewServerForHook](./api-javascript#previewserverforhook)

Same as [`configureServer`](/guide/api-plugin.html#configureserver) but for the preview server. It provides the [connect](https://github.com/senchalabs/connect) server and its underlying [http server](https://nodejs.org/api/http.html). Similarly to `configureServer`, the `configurePreviewServer` hook is called before other middlewares are installed. If you want to inject a middleware **after** other middlewares, you can return a function from `configurePreviewServer`, which will be called after internal middlewares are installed:
Same as [`configureServer`](/guide/api-plugin.html#configureserver) but for the preview server. Similarly to `configureServer`, the `configurePreviewServer` hook is called before other middlewares are installed. If you want to inject a middleware **after** other middlewares, you can return a function from `configurePreviewServer`, which will be called after internal middlewares are installed:

```js
const myPlugin = () => ({
Expand Down
1 change: 1 addition & 0 deletions packages/vite/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export type {
export type {
PreviewOptions,
PreviewServer,
PreviewServerForHook,
PreviewServerHook,
ResolvedPreviewOptions,
} from './preview'
Expand Down
5 changes: 3 additions & 2 deletions packages/vite/src/node/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ export interface Plugin extends RollupPlugin {
*/
configureServer?: ObjectHook<ServerHook>
/**
* Configure the preview server. The hook receives the connect server and
* its underlying http server.
* Configure the preview server. The hook receives the {@link PreviewServerForHook}
* instance. This can also be used to store a reference to the server
* for use in other hooks.
*
* The hooks are called before other middlewares are applied. A hook can
* return a post hook that will be called after other middlewares are
Expand Down
55 changes: 37 additions & 18 deletions packages/vite/src/node/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,31 +45,42 @@ export function resolvePreviewOptions(
}
}

export interface PreviewServer {
// TODO: merge with PreviewServer in Vite 5
export interface PreviewServerForHook {
/**
* The resolved vite config object
*/
config: ResolvedConfig
/**
* A connect app instance.
* - Can be used to attach custom middlewares to the preview server.
* - Can also be used as the handler function of a custom http server
* or as a middleware in any connect-style Node.js frameworks
*
* https://github.com/senchalabs/connect#use-middleware
*/
middlewares: Connect.Server
/**
* native Node http server instance
*/
httpServer: http.Server
/**
* The resolved urls Vite prints on the CLI
*/
resolvedUrls: ResolvedServerUrls
resolvedUrls: ResolvedServerUrls | null
/**
* Print server urls
*/
printUrls(): void
}

export interface PreviewServer extends PreviewServerForHook {
resolvedUrls: ResolvedServerUrls
}

export type PreviewServerHook = (
this: void,
server: {
middlewares: Connect.Server
httpServer: http.Server
},
server: PreviewServerForHook,
) => (() => void) | void | Promise<(() => void) | void>

/**
Expand Down Expand Up @@ -108,10 +119,27 @@ export async function preview(
)
setClientErrorHandler(httpServer, config.logger)

const options = config.preview
const logger = config.logger

const server: PreviewServerForHook = {
config,
middlewares: app,
httpServer,
resolvedUrls: null,
printUrls() {
if (server.resolvedUrls) {
printServerUrls(server.resolvedUrls, options.host, logger.info)
} else {
throw new Error('cannot print server URLs before server is listening.')
}
},
}

// apply server hooks from plugins
const postHooks: ((() => void) | void)[] = []
for (const hook of config.getSortedPluginHooks('configurePreviewServer')) {
postHooks.push(await hook({ middlewares: app, httpServer }))
postHooks.push(await hook(server))
}

// cors
Expand Down Expand Up @@ -153,11 +181,9 @@ export async function preview(
// apply post server hooks from plugins
postHooks.forEach((fn) => fn && fn())

const options = config.preview
const hostname = await resolveHostname(options.host)
const port = options.port ?? DEFAULT_PREVIEW_PORT
const protocol = options.https ? 'https' : 'http'
const logger = config.logger

const serverPort = await httpServerStart(httpServer, {
port,
Expand All @@ -166,7 +192,7 @@ export async function preview(
logger,
})

const resolvedUrls = await resolveServerUrls(
server.resolvedUrls = await resolveServerUrls(
httpServer,
config.preview,
config,
Expand All @@ -183,12 +209,5 @@ export async function preview(
)
}

return {
config,
httpServer,
resolvedUrls,
printUrls() {
printServerUrls(resolvedUrls, options.host, logger.info)
},
}
return server as PreviewServer
}

0 comments on commit 4c142ea

Please sign in to comment.