diff --git a/CHANGELOG.md b/CHANGELOG.md index ca6b44bd175..573abc03969 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,18 @@ Restrictions on array and object destructuring patterns in the previous release introduced a regression where arrays or objects in TypeScript code could fail to parse if they were wrapped in a double layer of parentheses. This was due to the speculative parsing of arrow function arguments. The regression has been fixed. +* Add the Go-specific `cli.ParseServeOptions()` API ([#834](https://github.com/evanw/esbuild/issues/834)) + + This API is specifically for people trying to emulate esbuild's CLI in Go. It lets you share esbuild's logic of parsing the `--serve=` and `--servedir=` flags. Use it like this: + + ```go + serveOptions, args, err := cli.ParseServeOptions([]string{ + "--serve=8000", + }) + buildOptions, err := cli.ParseBuildOptions(args) + result := api.Serve(serveOptions, buildOptions) + ``` + ## 0.8.48 * Fix some parsing edge cases ([#835](https://github.com/evanw/esbuild/issues/835)) diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go index 4be92e90433..ef21f643968 100644 --- a/pkg/cli/cli.go +++ b/pkg/cli/cli.go @@ -69,3 +69,22 @@ func ParseTransformOptions(osArgs []string) (options api.TransformOptions, err e err = parseOptionsImpl(osArgs, nil, &options) return } + +// This parses an array of strings into an options object suitable for passing +// to "api.Serve()". The remaining non-serve arguments are returned in another +// array to then be passed to "api.ParseBuildOptions()". Use this if you need +// to reuse the same argument parsing logic as the esbuild CLI. +// +// Example usage: +// +// serveOptions, args, err := cli.ParseServeOptions([]string{ +// "--serve=8000", +// }) +// +// buildOptions, err := cli.ParseBuildOptions(args) +// +// result := api.Serve(serveOptions, buildOptions) +// +func ParseServeOptions(osArgs []string) (options api.ServeOptions, remainingArgs []string, err error) { + return parseServeOptionsImpl(osArgs) +} diff --git a/pkg/cli/cli_impl.go b/pkg/cli/cli_impl.go index 2e564935f17..0624b71f934 100644 --- a/pkg/cli/cli_impl.go +++ b/pkg/cli/cli_impl.go @@ -687,7 +687,7 @@ func printSummary(osArgs []string, outputFiles []api.OutputFile, start time.Time logger.PrintSummary(osArgs, table, start) } -func serveImpl(osArgs []string) error { +func parseServeOptionsImpl(osArgs []string) (api.ServeOptions, []string, error) { host := "" portText := "0" servedir := "" @@ -711,17 +711,30 @@ func serveImpl(osArgs []string) error { var err error host, portText, err = net.SplitHostPort(portText) if err != nil { - return err + return api.ServeOptions{}, nil, err } } // Parse the port port, err := strconv.ParseInt(portText, 10, 32) if err != nil { - return err + return api.ServeOptions{}, nil, err } if port < 0 || port > 0xFFFF { - return fmt.Errorf("Invalid port number: %s", portText) + return api.ServeOptions{}, nil, fmt.Errorf("Invalid port number: %s", portText) + } + + return api.ServeOptions{ + Port: uint16(port), + Host: host, + Servedir: servedir, + }, filteredArgs, nil +} + +func serveImpl(osArgs []string) error { + serveOptions, filteredArgs, err := parseServeOptionsImpl(osArgs) + if err != nil { + return err } options := newBuildOptions() @@ -735,23 +748,18 @@ func serveImpl(osArgs []string) error { return err } - serveOptions := api.ServeOptions{ - Port: uint16(port), - Host: host, - Servedir: servedir, - OnRequest: func(args api.ServeOnRequestArgs) { - logger.PrintText(os.Stderr, logger.LevelInfo, filteredArgs, func(colors logger.Colors) string { - statusColor := colors.Red - if args.Status >= 200 && args.Status <= 299 { - statusColor = colors.Green - } else if args.Status >= 300 && args.Status <= 399 { - statusColor = colors.Yellow - } - return fmt.Sprintf("%s%s - %q %s%d%s [%dms]%s\n", - colors.Dim, args.RemoteAddress, args.Method+" "+args.Path, - statusColor, args.Status, colors.Dim, args.TimeInMS, colors.Default) - }) - }, + serveOptions.OnRequest = func(args api.ServeOnRequestArgs) { + logger.PrintText(os.Stderr, logger.LevelInfo, filteredArgs, func(colors logger.Colors) string { + statusColor := colors.Red + if args.Status >= 200 && args.Status <= 299 { + statusColor = colors.Green + } else if args.Status >= 300 && args.Status <= 399 { + statusColor = colors.Yellow + } + return fmt.Sprintf("%s%s - %q %s%d%s [%dms]%s\n", + colors.Dim, args.RemoteAddress, args.Method+" "+args.Path, + statusColor, args.Status, colors.Dim, args.TimeInMS, colors.Default) + }) } result, err := api.Serve(serveOptions, options)