diff --git a/v2/cmd/wails/internal/commands/dev/dev.go b/v2/cmd/wails/internal/commands/dev/dev.go index 97604ee33..e69c8fec0 100644 --- a/v2/cmd/wails/internal/commands/dev/dev.go +++ b/v2/cmd/wails/internal/commands/dev/dev.go @@ -183,6 +183,19 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error { signal.Notify(quitChannel, os.Interrupt, os.Kill, syscall.SIGTERM) exitCodeChannel := make(chan int, 1) + // frontend:dev:watcher command. + if command := projectConfig.DevWatcherCommand; command != "" { + closer, devServerURL, err := runFrontendDevWatcherCommand(cwd, command, projectConfig.FrontendDevServerURL == "auto") + if err != nil { + return err + } + if devServerURL != "" { + projectConfig.FrontendDevServerURL = devServerURL + flags.frontendDevServerURL = devServerURL + } + defer closer() + } + // Do initial build logger.Println("Building application for development...") debugBinaryProcess, appBinary, err := restartApp(buildOptions, nil, flags, exitCodeChannel) @@ -195,15 +208,6 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error { } }() - // frontend:dev:watcher command. - if command := projectConfig.DevWatcherCommand; command != "" { - closer, err := runFrontendDevWatcherCommand(cwd, command) - if err != nil { - return err - } - defer closer() - } - // open browser if flags.openBrowser { err = browser.OpenURL(devServerURL.String()) @@ -232,6 +236,12 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error { } LogGreen("Using reload debounce setting of %d milliseconds", flags.debounceMS) + // Show dev server URL in terminal after 3 seconds + go func() { + time.Sleep(3 * time.Second) + LogGreen("\n\nTo develop in the browser, navigate to: %s", devServerURL) + }() + // Watch for changes and trigger restartApp() debugBinaryProcess = doWatcherLoop(buildOptions, debugBinaryProcess, flags, watcher, exitCodeChannel, quitChannel, devServerURL) @@ -411,18 +421,31 @@ func loadAndMergeProjectConfig(cwd string, flags *devFlags) (*project.Project, e } // runFrontendDevWatcherCommand will run the `frontend:dev:watcher` command if it was given, ex- `npm run dev` -func runFrontendDevWatcherCommand(cwd string, devCommand string) (func(), error) { +func runFrontendDevWatcherCommand(cwd string, devCommand string, discoverViteServerURL bool) (func(), string, error) { ctx, cancel := context.WithCancel(context.Background()) + scanner := NewStdoutScanner() dir := filepath.Join(cwd, "frontend") cmdSlice := strings.Split(devCommand, " ") cmd := exec.CommandContext(ctx, cmdSlice[0], cmdSlice[1:]...) cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout + cmd.Stdout = scanner cmd.Dir = dir setParentGID(cmd) + if err := cmd.Start(); err != nil { cancel() - return nil, fmt.Errorf("Unable to start frontend DevWatcher: %w", err) + return nil, "", fmt.Errorf("unable to start frontend DevWatcher: %w", err) + } + + var viteServerURL string + if discoverViteServerURL { + select { + case serverURL := <-scanner.ViteServerURLChan: + viteServerURL = serverURL + case <-time.After(time.Second * 10): + cancel() + return nil, "", errors.New("failed to find Vite server URL") + } } LogGreen("Running frontend DevWatcher command: '%s'", devCommand) @@ -443,7 +466,7 @@ func runFrontendDevWatcherCommand(cwd string, devCommand string) (func(), error) LogGreen("DevWatcher command killed!") cancel() wg.Wait() - }, nil + }, viteServerURL, nil } // initialiseWatcher creates the project directory watcher that will trigger recompile @@ -550,12 +573,12 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc if dir == "" { continue } - path, err := filepath.Abs(dir) + thePath, err := filepath.Abs(dir) if err != nil { LogRed("Unable to expand reloadDir '%s': %s", dir, err) continue } - dirsThatTriggerAReload = append(dirsThatTriggerAReload, path) + dirsThatTriggerAReload = append(dirsThatTriggerAReload, thePath) } quit := false @@ -661,8 +684,8 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc } if assetDir != "" { - for path := range changedPaths { - if strings.HasPrefix(path, assetDir) { + for thePath := range changedPaths { + if strings.HasPrefix(thePath, assetDir) { reload = true break } diff --git a/v2/cmd/wails/internal/commands/dev/stdout_scanner.go b/v2/cmd/wails/internal/commands/dev/stdout_scanner.go new file mode 100644 index 000000000..d564b5481 --- /dev/null +++ b/v2/cmd/wails/internal/commands/dev/stdout_scanner.go @@ -0,0 +1,45 @@ +package dev + +import ( + "bufio" + "bytes" + "github.com/acarl005/stripansi" + "net/url" + "os" + "strings" +) + +// stdoutScanner acts as a stdout target that will scan the incoming +// data to find out the vite server url +type stdoutScanner struct { + ViteServerURLChan chan string +} + +// NewStdoutScanner creates a new stdoutScanner +func NewStdoutScanner() *stdoutScanner { + return &stdoutScanner{ + ViteServerURLChan: make(chan string, 2), + } +} + +// Write bytes to the scanner. Will copy the bytes to stdout +func (s *stdoutScanner) Write(data []byte) (n int, err error) { + match := bytes.Index(data, []byte("> Local:")) + if match != -1 { + sc := bufio.NewScanner(strings.NewReader(string(data))) + for sc.Scan() { + line := sc.Text() + index := strings.Index(line, "Local:") + line = strings.TrimSpace(line[index+6:]) + viteServerURL := stripansi.Strip(line) + LogGreen("Vite Server URL: %s", viteServerURL) + _, err := url.Parse(viteServerURL) + if err != nil { + LogRed(err.Error()) + } else { + s.ViteServerURLChan <- viteServerURL + } + } + } + return os.Stdout.Write(data) +} diff --git a/v2/cmd/wails/internal/commands/initialise/templates/base/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/base/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/base/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/base/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/lit-ts/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/lit-ts/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/lit-ts/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/lit-ts/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/lit/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/lit/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/lit/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/lit/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/plain/main.tmpl.go b/v2/cmd/wails/internal/commands/initialise/templates/templates/plain/main.tmpl.go deleted file mode 100644 index fc96ccb4e..000000000 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/plain/main.tmpl.go +++ /dev/null @@ -1,83 +0,0 @@ -package main - -import ( - "embed" - "log" - - "github.com/wailsapp/wails/v2/pkg/options/mac" - - "github.com/wailsapp/wails/v2" - "github.com/wailsapp/wails/v2/pkg/logger" - "github.com/wailsapp/wails/v2/pkg/options" - "github.com/wailsapp/wails/v2/pkg/options/windows" -) - -//go:embed frontend/src -var assets embed.FS - -//go:embed build/appicon.png -var icon []byte - -func main() { - // Create an instance of the app structure - app := NewApp() - - // Create application with options - err := wails.Run(&options.App{ - Title: "{{.ProjectName}}", - Width: 1024, - Height: 768, - MinWidth: 1024, - MinHeight: 768, - MaxWidth: 1280, - MaxHeight: 800, - DisableResize: false, - Fullscreen: false, - Frameless: false, - StartHidden: false, - HideWindowOnClose: false, - BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1}, - Assets: assets, - Menu: nil, - Logger: nil, - LogLevel: logger.DEBUG, - OnStartup: app.startup, - OnDomReady: app.domReady, - OnBeforeClose: app.beforeClose, - OnShutdown: app.shutdown, - WindowStartState: options.Normal, - Bind: []interface{}{ - app, - }, - // Windows platform specific options - Windows: &windows.Options{ - WebviewIsTransparent: false, - WindowIsTranslucent: false, - DisableWindowIcon: false, - // DisableFramelessWindowDecorations: false, - WebviewUserDataPath: "", - }, - Mac: &mac.Options{ - TitleBar: &mac.TitleBar{ - TitlebarAppearsTransparent: true, - HideTitle: false, - HideTitleBar: false, - FullSizeContent: false, - UseToolbar: false, - HideToolbarSeparator: true, - }, - Appearance: mac.NSAppearanceNameDarkAqua, - WebviewIsTransparent: true, - WindowIsTranslucent: true, - About: &mac.AboutInfo{ - Title: "Plain Template", - Message: "Part of the Wails projects", - Icon: icon, - }, - }, - }) - - if err != nil { - log.Fatal(err) - } -} diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/preact-ts/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/preact-ts/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/preact-ts/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/preact-ts/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/preact/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/preact/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/preact/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/preact/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/react-ts/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/react-ts/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/react-ts/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/react-ts/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/react/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/react/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/react/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/react/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte-ts/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte-ts/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte-ts/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte-ts/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/svelte/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla-ts/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla-ts/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla-ts/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla-ts/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/vanilla/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/frontend/package.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/frontend/package.json index 62c7fd6e1..2cfff6a47 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/frontend/package.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/frontend/package.json @@ -14,6 +14,7 @@ "@vitejs/plugin-vue": "^2.3.3", "typescript": "^4.5.4", "vite": "^2.9.9", - "vue-tsc": "^0.34.7" + "vue-tsc": "^0.34.7", + "@babel/types": "^7.17.10" } } \ No newline at end of file diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/vue-ts/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates/vue/wails.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/templates/vue/wails.tmpl.json index 95918763e..0bba43da6 100644 --- a/v2/cmd/wails/internal/commands/initialise/templates/templates/vue/wails.tmpl.json +++ b/v2/cmd/wails/internal/commands/initialise/templates/templates/vue/wails.tmpl.json @@ -4,7 +4,7 @@ "frontend:install": "npm install", "frontend:build": "npm run build", "frontend:dev:watcher": "npm run dev", - "frontend:dev:serverUrl": "http://localhost:3000", + "frontend:dev:serverUrl": "auto", "author": { "name": "{{.AuthorName}}", "email": "{{.AuthorEmail}}" diff --git a/v2/go.mod b/v2/go.mod index 2d227c31f..d15845920 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -38,6 +38,7 @@ require ( ) require ( + github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/bep/debounce v1.2.1 github.com/bitfield/script v0.19.0 github.com/go-ole/go-ole v1.2.6 diff --git a/v2/go.sum b/v2/go.sum index b9b91b1b8..9412a00fc 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -5,6 +5,8 @@ github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0 github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= diff --git a/website/docs/reference/project-config.mdx b/website/docs/reference/project-config.mdx index de612d5f7..1005dd010 100644 --- a/website/docs/reference/project-config.mdx +++ b/website/docs/reference/project-config.mdx @@ -15,7 +15,7 @@ The project config resides in the `wails.json` file in the project directory. Th "frontend:build": "[The command to build the assets, run in the frontend directory - often `npm run build`]", "frontend:dev": "[This command is the dev equivalent of frontend:build. If not specified falls back to frontend:build]", "frontend:dev:watcher": "[This command is run in a separate process on `wails dev`. Useful for 3rd party watchers or starting 3d party dev servers]", - "frontend:dev:serverUrl": "[URL to a 3rd party dev server to be used to serve assets, EG Vite", + "frontend:dev:serverUrl": "[URL to a 3rd party dev server to be used to serve assets, EG Vite. If this is set to 'auto' then the devServerUrl will be inferred from the Vite output]", "wailsjsdir": "[Relative path to the directory that the auto-generated JS modules will be created]", "version": "[Project config version]", "outputfilename": "[The name of the binary]",