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
Changes from 1 commit
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
30 changes: 29 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,9 @@ 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"')
// 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 <options>', 'Use specified Vite server options')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could not find any proper example of such documentation. Should I add a few lines to the README?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think that would do

.help()

cli
Expand All @@ -24,6 +28,7 @@ export interface CliOptions {
root?: string
config?: string
watch?: boolean
serverOptions?: ViteNodeServerOptions
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the option is provided by the consumer, it might not match ViteNodeServerOptions, so I'm cheating a little bit here.

However, we could rely on a TS guard to assert that the given options match the TS interface, but it would mean hardcoding the checks, and thus duplicating the source of truth between ViteNodeServerOptions and the TS guard. Concretely, both could be out of sync, leading to issues.

Do you see another way to achieve this without duplicating the source of truth? 🤔

'--'?: string[]
}

Expand All @@ -37,14 +42,17 @@ 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,
root: options.root,
})
await server.pluginContainer.buildStart({})

const node = new ViteNodeServer(server)
const node = new ViteNodeServer(server, options.serverOptions)

const runner = new ViteNodeRunner({
root: server.config.root,
Expand Down Expand Up @@ -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.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noticed that serverOptions.transformMode.ssr (and .web) only accept Regexes, while serverOptions.deps.inline (and .external) accepts both strings and Regexes.

  • Is that expected?
  • If so, would you mind giving a bit of context as why? 🙏

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't have a reason 👀
I guess just didn't notice. but to be honest I prefer using regexp always, because current solution for deps.inline as a string is not reliable on non-npm/pnpm package managers

}