mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 04:42:00 +08:00
parent
d1ae16ad3c
commit
1dec40db33
@ -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
|
||||
}
|
||||
|
45
v2/cmd/wails/internal/commands/dev/stdout_scanner.go
Normal file
45
v2/cmd/wails/internal/commands/dev/stdout_scanner.go
Normal file
@ -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)
|
||||
}
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
@ -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}}"
|
||||
|
@ -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}}"
|
||||
|
@ -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
|
||||
|
@ -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=
|
||||
|
@ -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]",
|
||||
|
Loading…
Reference in New Issue
Block a user