@web/dev-server
Version:
Dev server for web applications
139 lines (129 loc) • 3.43 kB
text/typescript
import commandLineArgs from 'command-line-args';
import commandLineUsage, { OptionDefinition } from 'command-line-usage';
import camelCase from 'camelcase';
import { DevServerConfig } from './DevServerConfig.js';
export interface DevServerCliArgs
extends Partial<
Pick<
DevServerConfig,
| 'rootDir'
| 'open'
| 'appIndex'
| 'preserveSymlinks'
| 'nodeResolve'
| 'watch'
| 'esbuildTarget'
>
> {
config?: string;
}
const options: (OptionDefinition & { description: string })[] = [
{
name: 'config',
alias: 'c',
type: String,
description: 'The file to read configuration from. Config entries are camelCases flags.',
},
{
name: 'root-dir',
alias: 'r',
type: String,
description:
'The root directory to serve files from. Defaults to the current working directory.',
},
{
name: 'base-path',
alias: 'b',
type: String,
description: 'Prefix to strip from requests URLs.',
},
{
name: 'open',
alias: 'o',
type: String,
description: 'Opens the browser on app-index, root dir or a custom path.',
},
{
name: 'app-index',
alias: 'a',
type: String,
description:
"The app's index.html file. When set, serves the index.html for non-file requests. Use this to enable SPA routing.",
},
{
name: 'preserve-symlinks',
description: "Don't follow symlinks when resolving module imports.",
type: Boolean,
},
{
name: 'node-resolve',
description: 'Resolve bare module imports using node resolution',
type: Boolean,
},
{
name: 'watch',
alias: 'w',
description: 'Reload the browser when files are changed.',
type: Boolean,
},
{
name: 'port',
alias: 'p',
description: 'Port to bind the server to.',
type: Number,
},
{
name: 'hostname',
alias: 'h',
description: 'Hostname to bind the server to.',
},
{
name: 'esbuild-target',
type: String,
multiple: true,
description:
'JS language target to compile down to using esbuild. Recommended value is "auto", which compiles based on user agent. Check the docs for more options.',
},
{
name: 'debug',
type: Boolean,
description: 'Whether to log debug messages.',
},
{
name: 'help',
type: Boolean,
description: 'List all possible commands.',
},
];
export interface ReadCliArgsParams {
argv?: string[];
}
export function readCliArgs({ argv = process.argv }: ReadCliArgsParams = {}): DevServerCliArgs {
const cliArgs = commandLineArgs(options, { argv, partial: true });
// when the open flag is used without arguments, it defaults to null. treat this as "true"
if ('open' in cliArgs && typeof cliArgs.open !== 'string') {
cliArgs.open = true;
}
if ('help' in cliArgs) {
/* eslint-disable-next-line no-console */
console.log(
commandLineUsage([
{
header: 'Web Dev Server',
content: 'Dev Server for web development.',
},
{
header: 'Usage',
content: 'web-dev-server [options...]' + '\nwds [options...]',
},
{ header: 'Options', optionList: options },
]),
);
process.exit();
}
const cliArgsConfig: DevServerCliArgs = {};
for (const [key, value] of Object.entries(cliArgs)) {
cliArgsConfig[camelCase(key) as keyof DevServerCliArgs] = value;
}
return cliArgsConfig;
}