cmd/tsconnect: add dev-pkg command for two-sided development
Allows imports of the NPM package added by 1a093ef482
to be replaced with import("http://localhost:9090/pkg/pkg.js"), so that
changes can be made in parallel to both the module and code that uses
it (without any need for NPM publishing or even building of the package).
Updates #5415
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This commit is contained in:
parent
672c2c8de8
commit
2f702b150e
|
@ -38,3 +38,12 @@ The client is also available as an NPM package. To build it, run:
|
||||||
```
|
```
|
||||||
|
|
||||||
That places the output in the `pkg/` directory, which may then be uploaded to a package registry (or installed from the file path directly).
|
That places the output in the `pkg/` directory, which may then be uploaded to a package registry (or installed from the file path directly).
|
||||||
|
|
||||||
|
To do two-sided development (on both the NPM package and code that uses it), run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./tool/go run ./cmd/tsconnect dev-pkg
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
This serves the module at http://localhost:9090/pkg/pkg.js and the generated wasm file at http://localhost:9090/pkg/main.wasm. The two files can be used as drop-in replacements for normal imports of the NPM module.
|
||||||
|
|
|
@ -11,13 +11,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
esbuild "github.com/evanw/esbuild/pkg/api"
|
|
||||||
"github.com/tailscale/hujson"
|
"github.com/tailscale/hujson"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runBuildPkg() {
|
func runBuildPkg() {
|
||||||
buildOptions, err := commonSetup(prodMode)
|
buildOptions, err := commonPkgSetup(prodMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Cannot setup: %v", err)
|
log.Fatalf("Cannot setup: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -31,10 +30,6 @@ func runBuildPkg() {
|
||||||
log.Fatalf("Cannot clean %s: %v", *pkgDir, err)
|
log.Fatalf("Cannot clean %s: %v", *pkgDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buildOptions.EntryPoints = []string{"src/pkg/pkg.ts", "src/pkg/pkg.css"}
|
|
||||||
buildOptions.Outdir = *pkgDir
|
|
||||||
buildOptions.Format = esbuild.FormatESModule
|
|
||||||
buildOptions.AssetNames = "[name]"
|
|
||||||
buildOptions.Write = true
|
buildOptions.Write = true
|
||||||
buildOptions.MinifyWhitespace = true
|
buildOptions.MinifyWhitespace = true
|
||||||
buildOptions.MinifyIdentifiers = true
|
buildOptions.MinifyIdentifiers = true
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
@ -68,6 +69,18 @@ func commonSetup(dev bool) (*esbuild.BuildOptions, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func commonPkgSetup(dev bool) (*esbuild.BuildOptions, error) {
|
||||||
|
buildOptions, err := commonSetup(dev)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
buildOptions.EntryPoints = []string{"src/pkg/pkg.ts", "src/pkg/pkg.css"}
|
||||||
|
buildOptions.Outdir = *pkgDir
|
||||||
|
buildOptions.Format = esbuild.FormatESModule
|
||||||
|
buildOptions.AssetNames = "[name]"
|
||||||
|
return buildOptions, nil
|
||||||
|
}
|
||||||
|
|
||||||
// cleanDir removes files from dirPath, except the ones specified by
|
// cleanDir removes files from dirPath, except the ones specified by
|
||||||
// preserveFiles.
|
// preserveFiles.
|
||||||
func cleanDir(dirPath string, preserveFiles ...string) error {
|
func cleanDir(dirPath string, preserveFiles ...string) error {
|
||||||
|
@ -90,6 +103,27 @@ func cleanDir(dirPath string, preserveFiles ...string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runEsbuildServe(buildOptions esbuild.BuildOptions) {
|
||||||
|
host, portStr, err := net.SplitHostPort(*addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Cannot parse addr: %v", err)
|
||||||
|
}
|
||||||
|
port, err := strconv.ParseUint(portStr, 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Cannot parse port: %v", err)
|
||||||
|
}
|
||||||
|
result, err := esbuild.Serve(esbuild.ServeOptions{
|
||||||
|
Port: uint16(port),
|
||||||
|
Host: host,
|
||||||
|
Servedir: "./",
|
||||||
|
}, buildOptions)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Cannot start esbuild server: %v", err)
|
||||||
|
}
|
||||||
|
log.Printf("Listening on http://%s:%d\n", result.Host, result.Port)
|
||||||
|
result.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func runEsbuild(buildOptions esbuild.BuildOptions) esbuild.BuildResult {
|
func runEsbuild(buildOptions esbuild.BuildOptions) esbuild.BuildResult {
|
||||||
log.Printf("Running esbuild...\n")
|
log.Printf("Running esbuild...\n")
|
||||||
result := esbuild.Build(buildOptions)
|
result := esbuild.Build(buildOptions)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func runDevPkg() {
|
||||||
|
buildOptions, err := commonPkgSetup(devMode)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Cannot setup: %v", err)
|
||||||
|
}
|
||||||
|
runEsbuildServe(*buildOptions)
|
||||||
|
}
|
|
@ -6,10 +6,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
esbuild "github.com/evanw/esbuild/pkg/api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func runDev() {
|
func runDev() {
|
||||||
|
@ -17,22 +13,5 @@ func runDev() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Cannot setup: %v", err)
|
log.Fatalf("Cannot setup: %v", err)
|
||||||
}
|
}
|
||||||
host, portStr, err := net.SplitHostPort(*addr)
|
runEsbuildServe(*buildOptions)
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Cannot parse addr: %v", err)
|
|
||||||
}
|
|
||||||
port, err := strconv.ParseUint(portStr, 10, 16)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Cannot parse port: %v", err)
|
|
||||||
}
|
|
||||||
result, err := esbuild.Serve(esbuild.ServeOptions{
|
|
||||||
Port: uint16(port),
|
|
||||||
Host: host,
|
|
||||||
Servedir: "./",
|
|
||||||
}, *buildOptions)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Cannot start esbuild server: %v", err)
|
|
||||||
}
|
|
||||||
log.Printf("Listening on http://%s:%d\n", result.Host, result.Port)
|
|
||||||
result.Wait()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ func main() {
|
||||||
switch flag.Arg(0) {
|
switch flag.Arg(0) {
|
||||||
case "dev":
|
case "dev":
|
||||||
runDev()
|
runDev()
|
||||||
|
case "dev-pkg":
|
||||||
|
runDevPkg()
|
||||||
case "build":
|
case "build":
|
||||||
runBuild()
|
runBuild()
|
||||||
case "build-pkg":
|
case "build-pkg":
|
||||||
|
|
Loading…
Reference in New Issue