From f1e83239751278b433c7ac2bde4d971b8ea7338d Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Tue, 10 May 2022 09:14:45 +0200 Subject: [PATCH 1/5] Wip: Basic implemenetation --- packages/vite-node/src/cli.ts | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/vite-node/src/cli.ts b/packages/vite-node/src/cli.ts index 3867136a6714..28d9abd52f4c 100644 --- a/packages/vite-node/src/cli.ts +++ b/packages/vite-node/src/cli.ts @@ -4,6 +4,7 @@ import { createServer } from 'vite' import { version } from '../package.json' import { ViteNodeServer } from './server' import { ViteNodeRunner } from './client' +import type { ViteNodeServerOptions } from './types' const cli = cac('vite-node') @@ -12,6 +13,9 @@ cli .option('-r, --root ', 'Use specified root directory') .option('-c, --config ', 'Use specified config file') .option('-w, --watch', 'Restart on file changes, similar to "nodemon"') + // TODO: How could we document this? Ideally, we should link to the + // TODO: ViteNodeServerOptions type since it's the source of truth. + .option('--server-options ', 'Use specified Vite server options') .help() cli @@ -24,6 +28,7 @@ export interface CliOptions { root?: string config?: string watch?: boolean + serverOptions?: ViteNodeServerOptions '--'?: string[] } @@ -37,6 +42,9 @@ async function run(files: string[], options: CliOptions = {}) { // forward argv process.argv = [...process.argv.slice(0, 2), ...(options['--'] || [])] + if (options.serverOptions) + parseServerOptions(options.serverOptions) + const server = await createServer({ logLevel: 'error', configFile: options.config, @@ -44,7 +52,7 @@ async function run(files: string[], options: CliOptions = {}) { }) await server.pluginContainer.buildStart({}) - const node = new ViteNodeServer(server) + const node = new ViteNodeServer(server, options.serverOptions) const runner = new ViteNodeRunner({ root: server.config.root, @@ -81,3 +89,23 @@ async function run(files: string[], options: CliOptions = {}) { await runner.executeFile(file) }) } + +function parseServerOptions(serverOptions: ViteNodeServerOptions) { + if (serverOptions.deps && serverOptions.deps.inline) { + serverOptions.deps.inline = serverOptions.deps.inline.map((dep) => { + return typeof dep === 'string' && dep.startsWith('/') && dep.endsWith('/') + ? new RegExp(dep) + : dep + }) + } + + if (serverOptions.deps && serverOptions.deps.external) { + serverOptions.deps.external = serverOptions.deps.external.map((dep) => { + return typeof dep === 'string' && dep.startsWith('/') && dep.endsWith('/') + ? new RegExp(dep) + : dep + }) + } + + // TODO: Handle serverOptions.transformMode. +} From 444c806335be367353061442cf1d256c5ae8c999 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Mon, 16 May 2022 19:17:25 +0200 Subject: [PATCH 2/5] Feat: Compute CLI types dynamically --- packages/vite-node/src/cli.ts | 52 ++++++++++++++++++++------------- packages/vite-node/src/types.ts | 13 +++++++++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/packages/vite-node/src/cli.ts b/packages/vite-node/src/cli.ts index 28d9abd52f4c..2edea17958d3 100644 --- a/packages/vite-node/src/cli.ts +++ b/packages/vite-node/src/cli.ts @@ -4,7 +4,7 @@ import { createServer } from 'vite' import { version } from '../package.json' import { ViteNodeServer } from './server' import { ViteNodeRunner } from './client' -import type { ViteNodeServerOptions } from './types' +import type { ViteNodeServerOptions, ViteNodeServerOptionsCLI } from './types' const cli = cac('vite-node') @@ -28,7 +28,7 @@ export interface CliOptions { root?: string config?: string watch?: boolean - serverOptions?: ViteNodeServerOptions + serverOptions?: ViteNodeServerOptionsCLI '--'?: string[] } @@ -42,8 +42,9 @@ async function run(files: string[], options: CliOptions = {}) { // forward argv process.argv = [...process.argv.slice(0, 2), ...(options['--'] || [])] - if (options.serverOptions) - parseServerOptions(options.serverOptions) + const parsedServerOptions = options.serverOptions + ? parseServerOptions(options.serverOptions) + : undefined const server = await createServer({ logLevel: 'error', @@ -52,7 +53,7 @@ async function run(files: string[], options: CliOptions = {}) { }) await server.pluginContainer.buildStart({}) - const node = new ViteNodeServer(server, options.serverOptions) + const node = new ViteNodeServer(server, parsedServerOptions) const runner = new ViteNodeRunner({ root: server.config.root, @@ -90,22 +91,31 @@ async function run(files: string[], options: CliOptions = {}) { }) } -function parseServerOptions(serverOptions: ViteNodeServerOptions) { - if (serverOptions.deps && serverOptions.deps.inline) { - serverOptions.deps.inline = serverOptions.deps.inline.map((dep) => { - return typeof dep === 'string' && dep.startsWith('/') && dep.endsWith('/') - ? new RegExp(dep) - : dep - }) - } +function parseServerOptions(serverOptions: ViteNodeServerOptionsCLI): ViteNodeServerOptions { + return { + ...serverOptions, - if (serverOptions.deps && serverOptions.deps.external) { - serverOptions.deps.external = serverOptions.deps.external.map((dep) => { - return typeof dep === 'string' && dep.startsWith('/') && dep.endsWith('/') - ? new RegExp(dep) - : dep - }) - } + deps: { + ...serverOptions.deps, + + inline: serverOptions.deps?.inline?.map((dep) => { + return dep.startsWith('/') && dep.endsWith('/') + ? new RegExp(dep) + : dep + }), + + external: serverOptions.deps?.external?.map((dep) => { + return dep.startsWith('/') && dep.endsWith('/') + ? new RegExp(dep) + : dep + }), + }, + + transformMode: { + ...serverOptions.transformMode, - // TODO: Handle serverOptions.transformMode. + ssr: serverOptions.transformMode?.ssr?.map(dep => new RegExp(dep)), + web: serverOptions.transformMode?.ssr?.map(dep => new RegExp(dep)), + }, + } } diff --git a/packages/vite-node/src/types.ts b/packages/vite-node/src/types.ts index 06666b4c2cb6..ccaf96f948e2 100644 --- a/packages/vite-node/src/types.ts +++ b/packages/vite-node/src/types.ts @@ -77,4 +77,17 @@ export interface ViteNodeServerOptions { } } +type Optional = T | undefined +type ComputeViteNodeServerOptionsCLI> = { + [K in keyof T]: T[K] extends Optional + ? string[] + : T[K] extends Optional<(string | RegExp)[]> + ? string[] + : T[K] extends Optional> + ? ComputeViteNodeServerOptionsCLI + : T[K] +} + +export type ViteNodeServerOptionsCLI = ComputeViteNodeServerOptionsCLI + export type { ModuleCacheMap } From 2a96ef82e524f9ef2b85d9b8212652ba144d6d33 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Mon, 16 May 2022 20:23:34 +0200 Subject: [PATCH 3/5] Doc: Add dot-syntax documentation --- packages/vite-node/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/vite-node/README.md b/packages/vite-node/README.md index e2e3708e8f22..bcafb080b1f7 100644 --- a/packages/vite-node/README.md +++ b/packages/vite-node/README.md @@ -27,6 +27,16 @@ Options: npx vite-node -h ``` +### ViteNodeServer options + +[All `ViteNodeServer` options](https://github.com/vitest-dev/vitest/blob/main/packages/vite-node/src/types.ts#L61-L78) are supported by the CLI. They may be defined through the dot syntax, as shown below: + +```bash +npx vite-node --server-options.deps.inline="module-name" --server-options.deps.external="/module-regexp/" index.ts +``` + +Note that for options supporting RegExps, strings passed to the CLI must start _and_ end with a `/`; + ## Programmatic Usage In Vite Node, the server and runner (client) are separated, so you can integrate them in different contexts (workers, cross-process, or remote) if needed. The demo below shows a simple example of having both (server and runner) running in the same context From 45e9846111b643489dd3deafedca4abd2ab49fa9 Mon Sep 17 00:00:00 2001 From: Antoine Rey Date: Wed, 18 May 2022 15:19:34 +0200 Subject: [PATCH 4/5] Refactor: Remove todo --- packages/vite-node/src/cli.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/vite-node/src/cli.ts b/packages/vite-node/src/cli.ts index 2edea17958d3..c1103db1f097 100644 --- a/packages/vite-node/src/cli.ts +++ b/packages/vite-node/src/cli.ts @@ -13,8 +13,6 @@ cli .option('-r, --root ', 'Use specified root directory') .option('-c, --config ', 'Use specified config file') .option('-w, --watch', 'Restart on file changes, similar to "nodemon"') - // TODO: How could we document this? Ideally, we should link to the - // TODO: ViteNodeServerOptions type since it's the source of truth. .option('--server-options ', 'Use specified Vite server options') .help() From 1ce975bd1a1ac6b4a9e4c7856e42fed48bb20ed6 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sun, 29 May 2022 15:51:52 +0800 Subject: [PATCH 5/5] chore: update --- packages/vite-node/README.md | 4 ++-- packages/vite-node/src/cli.ts | 26 ++++++++++++++++++-------- packages/vite-node/src/types.ts | 13 ------------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/packages/vite-node/README.md b/packages/vite-node/README.md index 7207aa8da256..9f24d4833232 100644 --- a/packages/vite-node/README.md +++ b/packages/vite-node/README.md @@ -27,12 +27,12 @@ Options: npx vite-node -h ``` -### ViteNodeServer options +### Options via CLI [All `ViteNodeServer` options](https://github.com/vitest-dev/vitest/blob/main/packages/vite-node/src/types.ts#L61-L78) are supported by the CLI. They may be defined through the dot syntax, as shown below: ```bash -npx vite-node --server-options.deps.inline="module-name" --server-options.deps.external="/module-regexp/" index.ts +npx vite-node --options.deps.inline="module-name" --options.deps.external="/module-regexp/" index.ts ``` Note that for options supporting RegExps, strings passed to the CLI must start _and_ end with a `/`; diff --git a/packages/vite-node/src/cli.ts b/packages/vite-node/src/cli.ts index 253465876592..37dfff78123a 100644 --- a/packages/vite-node/src/cli.ts +++ b/packages/vite-node/src/cli.ts @@ -4,7 +4,7 @@ import { createServer } from 'vite' import { version } from '../package.json' import { ViteNodeServer } from './server' import { ViteNodeRunner } from './client' -import type { ViteNodeServerOptions, ViteNodeServerOptionsCLI } from './types' +import type { ViteNodeServerOptions } from './types' const cli = cac('vite-node') @@ -13,7 +13,7 @@ cli .option('-r, --root ', 'Use specified root directory') .option('-c, --config ', 'Use specified config file') .option('-w, --watch', 'Restart on file changes, similar to "nodemon"') - .option('--server-options ', 'Use specified Vite server options') + .option('--options ', 'Use specified Vite server options') .help() cli @@ -26,7 +26,7 @@ export interface CliOptions { root?: string config?: string watch?: boolean - serverOptions?: ViteNodeServerOptionsCLI + options?: ViteNodeServerOptionsCLI '--'?: string[] } @@ -40,8 +40,8 @@ async function run(files: string[], options: CliOptions = {}) { // forward argv process.argv = [...process.argv.slice(0, 2), ...(options['--'] || [])] - const parsedServerOptions = options.serverOptions - ? parseServerOptions(options.serverOptions) + const parsedServerOptions = options.options + ? parseServerOptions(options.options) : undefined const server = await createServer({ @@ -92,16 +92,13 @@ async function run(files: string[], options: CliOptions = {}) { function parseServerOptions(serverOptions: ViteNodeServerOptionsCLI): ViteNodeServerOptions { return { ...serverOptions, - deps: { ...serverOptions.deps, - inline: serverOptions.deps?.inline?.map((dep) => { return dep.startsWith('/') && dep.endsWith('/') ? new RegExp(dep) : dep }), - external: serverOptions.deps?.external?.map((dep) => { return dep.startsWith('/') && dep.endsWith('/') ? new RegExp(dep) @@ -117,3 +114,16 @@ function parseServerOptions(serverOptions: ViteNodeServerOptionsCLI): ViteNodeSe }, } } + +type Optional = T | undefined +type ComputeViteNodeServerOptionsCLI> = { + [K in keyof T]: T[K] extends Optional + ? string[] + : T[K] extends Optional<(string | RegExp)[]> + ? string[] + : T[K] extends Optional> + ? ComputeViteNodeServerOptionsCLI + : T[K] +} + +export type ViteNodeServerOptionsCLI = ComputeViteNodeServerOptionsCLI diff --git a/packages/vite-node/src/types.ts b/packages/vite-node/src/types.ts index ccaf96f948e2..06666b4c2cb6 100644 --- a/packages/vite-node/src/types.ts +++ b/packages/vite-node/src/types.ts @@ -77,17 +77,4 @@ export interface ViteNodeServerOptions { } } -type Optional = T | undefined -type ComputeViteNodeServerOptionsCLI> = { - [K in keyof T]: T[K] extends Optional - ? string[] - : T[K] extends Optional<(string | RegExp)[]> - ? string[] - : T[K] extends Optional> - ? ComputeViteNodeServerOptionsCLI - : T[K] -} - -export type ViteNodeServerOptionsCLI = ComputeViteNodeServerOptionsCLI - export type { ModuleCacheMap }