Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vite-node): options via CLI (fixes #1208) #1215

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/vite-node/README.md
Expand Up @@ -27,6 +27,16 @@ Options:
npx vite-node -h
```

### 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 --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 `/`;

## 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
Expand Down
48 changes: 47 additions & 1 deletion packages/vite-node/src/cli.ts
Expand Up @@ -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')

Expand All @@ -12,6 +13,7 @@ cli
.option('-r, --root <path>', 'Use specified root directory')
.option('-c, --config <path>', 'Use specified config file')
.option('-w, --watch', 'Restart on file changes, similar to "nodemon"')
.option('--options <options>', 'Use specified Vite server options')
.help()

cli
Expand All @@ -24,6 +26,7 @@ export interface CliOptions {
root?: string
config?: string
watch?: boolean
options?: ViteNodeServerOptionsCLI
'--'?: string[]
}

Expand All @@ -37,14 +40,18 @@ async function run(files: string[], options: CliOptions = {}) {
// forward argv
process.argv = [...process.argv.slice(0, 2), ...(options['--'] || [])]

const parsedServerOptions = options.options
? parseServerOptions(options.options)
: undefined

const server = await createServer({
logLevel: 'error',
configFile: options.config,
root: options.root,
})
await server.pluginContainer.buildStart({})

const node = new ViteNodeServer(server)
const node = new ViteNodeServer(server, parsedServerOptions)

const runner = new ViteNodeRunner({
root: server.config.root,
Expand Down Expand Up @@ -81,3 +88,42 @@ async function run(files: string[], options: CliOptions = {}) {
await runner.executeFile(file)
})
}

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)
: dep
}),
},

transformMode: {
...serverOptions.transformMode,

ssr: serverOptions.transformMode?.ssr?.map(dep => new RegExp(dep)),
web: serverOptions.transformMode?.ssr?.map(dep => new RegExp(dep)),
},
}
}

type Optional<T> = T | undefined
type ComputeViteNodeServerOptionsCLI<T extends Record<string, any>> = {
[K in keyof T]: T[K] extends Optional<RegExp[]>
? string[]
: T[K] extends Optional<(string | RegExp)[]>
? string[]
: T[K] extends Optional<Record<string, any>>
? ComputeViteNodeServerOptionsCLI<T[K]>
: T[K]
}

export type ViteNodeServerOptionsCLI = ComputeViteNodeServerOptionsCLI<ViteNodeServerOptions>