diff --git a/v2/cmd/wails/internal/commands/dev/dev.go b/v2/cmd/wails/internal/commands/dev/dev.go
index df452d1f..169c6168 100644
--- a/v2/cmd/wails/internal/commands/dev/dev.go
+++ b/v2/cmd/wails/internal/commands/dev/dev.go
@@ -63,6 +63,7 @@ type devFlags struct {
compilerCommand string
assetDir string
extensions string
+ reloadDirs string
openBrowser bool
noReload bool
wailsjsdir string
@@ -83,8 +84,9 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
flags := defaultDevFlags()
command.StringFlag("ldflags", "optional ldflags", &flags.ldflags)
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &flags.compilerCommand)
- command.StringFlag("assetdir", "Serve assets from the given directory", &flags.assetDir)
+ command.StringFlag("assetdir", "Serve assets from the given directory instead of using the provided asset FS", &flags.assetDir)
command.StringFlag("e", "Extensions to trigger rebuilds (comma separated) eg go", &flags.extensions)
+ command.StringFlag("reloaddirs", "Additional directories to trigger reloads (comma separated)", &flags.reloadDirs)
command.BoolFlag("browser", "Open application in browser", &flags.openBrowser)
command.BoolFlag("noreload", "Disable reload on asset change", &flags.noReload)
command.StringFlag("wailsjsdir", "Directory to generate the Wails JS modules", &flags.wailsjsdir)
@@ -301,10 +303,6 @@ func loadAndMergeProjectConfig(cwd string, flags *devFlags) (*project.Project, e
var shouldSaveConfig bool
- if projectConfig.AssetDirectory == "" && flags.assetDir == "" {
- return nil, fmt.Errorf("No asset directory provided. Please use -assetdir to indicate which directory contains your built assets.")
- }
-
if flags.assetDir == "" && projectConfig.AssetDirectory != "" {
flags.assetDir = projectConfig.AssetDirectory
}
@@ -313,9 +311,19 @@ func loadAndMergeProjectConfig(cwd string, flags *devFlags) (*project.Project, e
projectConfig.AssetDirectory = filepath.ToSlash(flags.assetDir)
}
- flags.assetDir, err = filepath.Abs(flags.assetDir)
- if err != nil {
- return nil, err
+ if flags.assetDir != "" {
+ flags.assetDir, err = filepath.Abs(flags.assetDir)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if flags.reloadDirs == "" && projectConfig.ReloadDirectories != "" {
+ flags.reloadDirs = projectConfig.ReloadDirectories
+ }
+
+ if flags.reloadDirs != projectConfig.ReloadDirectories {
+ projectConfig.ReloadDirectories = filepath.ToSlash(flags.reloadDirs)
}
if flags.devServerURL == defaultDevServerURL && projectConfig.DevServerURL != defaultDevServerURL && projectConfig.DevServerURL != "" {
@@ -503,11 +511,26 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
newBinaryProcess *process.Process
)
var extensionsThatTriggerARebuild = sliceToMap(strings.Split(flags.extensions, ","))
+ var dirsThatTriggerAReload []string
+ for _, dir := range strings.Split(flags.reloadDirs, ",") {
+ if dir == "" {
+ continue
+ }
+ path, err := filepath.Abs(dir)
+ if err != nil {
+ LogRed("Unable to expand reloadDir '%s': %s", dir, err)
+ continue
+ }
+ dirsThatTriggerAReload = append(dirsThatTriggerAReload, path)
+ }
+
quit := false
interval := time.Duration(flags.debounceMS) * time.Millisecond
timer := time.NewTimer(interval)
rebuild := false
reload := false
+ assetDir := ""
+ changedPaths := map[string]struct{}{}
for quit == false {
//reload := false
select {
@@ -519,12 +542,13 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
// Check for file writes
if item.Op&fsnotify.Write == fsnotify.Write {
// Ignore directories
- if fs.DirExists(item.Name) {
+ itemName := item.Name
+ if fs.DirExists(itemName) {
continue
}
// Iterate all file patterns
- ext := filepath.Ext(item.Name)
+ ext := filepath.Ext(itemName)
if ext != "" {
ext = ext[1:]
if _, exists := extensionsThatTriggerARebuild[ext]; exists {
@@ -534,9 +558,17 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
}
}
- if strings.HasPrefix(item.Name, flags.assetDir) {
- reload = true
+ for _, reloadDir := range dirsThatTriggerAReload {
+ if strings.HasPrefix(itemName, reloadDir) {
+ reload = true
+ break
+ }
}
+
+ if !reload {
+ changedPaths[filepath.Dir(itemName)] = struct{}{}
+ }
+
timer.Reset(interval)
}
// Check for new directories
@@ -568,6 +600,35 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
debugBinaryProcess = newBinaryProcess
}
}
+ if len(changedPaths) != 0 {
+ if assetDir == "" {
+ resp, err := http.Get("http://localhost:34115/wails/assetdir")
+ if err != nil {
+ LogRed("Error during retrieving assetdir: %s", err.Error())
+ } else {
+ content, err := io.ReadAll(resp.Body)
+ if err != nil {
+ LogRed("Error reading assetdir from devserver: %s", err.Error())
+ } else {
+ assetDir = string(content)
+ }
+ resp.Body.Close()
+ }
+ }
+
+ if assetDir != "" {
+ for path := range changedPaths {
+ if strings.HasPrefix(path, assetDir) {
+ reload = true
+ break
+ }
+ }
+ } else if len(dirsThatTriggerAReload) == 0 {
+ LogRed("Reloading couldn't be triggered: Please specify -assetdir or -reloaddirs")
+ }
+
+ changedPaths = map[string]struct{}{}
+ }
if reload {
reload = false
_, err = http.Get("http://localhost:34115/wails/reload")
diff --git a/v2/cmd/wails/internal/commands/generate/template/base/NEXTSTEPS.md.template b/v2/cmd/wails/internal/commands/generate/template/base/NEXTSTEPS.md.template
index a357acd8..5363d10f 100644
--- a/v2/cmd/wails/internal/commands/generate/template/base/NEXTSTEPS.md.template
+++ b/v2/cmd/wails/internal/commands/generate/template/base/NEXTSTEPS.md.template
@@ -10,7 +10,6 @@ The next steps to complete the template are:
- It is really important to ensure `helpurl` is valid as this is where users of the template will be directed for help.
2. Update `README.md`.
3. Edit `wails.json` and ensure all fields are correct, especially:
- - `assetdir` - path to your assets
- `wailsjsdir` - path to generate wailsjs modules
- `frontend:install` - The command to install your frontend dependencies
- `frontend:build` - The command to build your frontend
diff --git a/v2/cmd/wails/internal/commands/generate/template/base/wails.tmpl.json b/v2/cmd/wails/internal/commands/generate/template/base/wails.tmpl.json
index b8d08108..63c4e6fe 100644
--- a/v2/cmd/wails/internal/commands/generate/template/base/wails.tmpl.json
+++ b/v2/cmd/wails/internal/commands/generate/template/base/wails.tmpl.json
@@ -1,7 +1,6 @@
{
"name": "{{.ProjectName}}",
"outputfilename": "{{.BinaryName}}",
- "assetdir": "frontend/dist",
"frontend:install": "npm install",
"frontend:build": "npm run build",
"author": {
diff --git a/v2/cmd/wails/internal/commands/initialise/templates/ides/goland/workspace.tmpl.xml b/v2/cmd/wails/internal/commands/initialise/templates/ides/goland/workspace.tmpl.xml
index 42f98045..9727844b 100644
--- a/v2/cmd/wails/internal/commands/initialise/templates/ides/goland/workspace.tmpl.xml
+++ b/v2/cmd/wails/internal/commands/initialise/templates/ides/goland/workspace.tmpl.xml
@@ -36,7 +36,6 @@
-
diff --git a/v2/cmd/wails/internal/commands/initialise/templates/ides/vscode/launch.tmpl.json b/v2/cmd/wails/internal/commands/initialise/templates/ides/vscode/launch.tmpl.json
index d03d5ccd..005f9bc4 100644
--- a/v2/cmd/wails/internal/commands/initialise/templates/ides/vscode/launch.tmpl.json
+++ b/v2/cmd/wails/internal/commands/initialise/templates/ides/vscode/launch.tmpl.json
@@ -9,11 +9,7 @@
"program": "${workspaceFolder}/{{.PathToDesktopBinary}}",
"preLaunchTask": "build",
"cwd": "${workspaceFolder}",
- "env": {},
- "args": [
- "-assetdir",
- "{{.AssetDir}}"
- ]
+ "env": {}
}
]
}
\ No newline at end of file
diff --git a/v2/cmd/wails/internal/commands/initialise/templates/templates.go b/v2/cmd/wails/internal/commands/initialise/templates/templates.go
index 64191678..2c81e05b 100644
--- a/v2/cmd/wails/internal/commands/initialise/templates/templates.go
+++ b/v2/cmd/wails/internal/commands/initialise/templates/templates.go
@@ -42,7 +42,6 @@ type Data struct {
AuthorNameAndEmail string
WailsDirectory string
GoSDKPath string
- AssetDir string
WindowsFlags string
CGOEnabled string
OutputFile string
@@ -60,7 +59,6 @@ type Options struct {
InitGit bool
AuthorName string
AuthorEmail string
- AssetDir string
IDE string
ProjectNameFilename string // The project name but as a valid filename
WailsVersion string
@@ -261,7 +259,6 @@ func Install(options *Options) (bool, *Template, error) {
AuthorName: options.AuthorName,
WailsVersion: options.WailsVersion,
GoSDKPath: options.GoSDKPath,
- AssetDir: options.AssetDir,
}
// Create a formatted name and email combo.
@@ -408,22 +405,6 @@ func installIDEFiles(o ideOptions) error {
binaryName += ".exe"
}
- // Parse wails.json for assetdir
- wailsJSONBytes, err := os.ReadFile(filepath.Join(o.options.TargetDir, "wails.json"))
- if err != nil {
- return err
- }
- var wailsJSON map[string]interface{}
- err = json.Unmarshal(wailsJSONBytes, &wailsJSON)
- if err != nil {
- return err
- }
- assetDir := wailsJSON["assetdir"]
- if assetDir == "" {
- return fmt.Errorf("Unable to find 'assetdir' in 'wails.json' ")
- }
-
- o.options.AssetDir = assetDir.(string)
o.options.PathToDesktopBinary = filepath.ToSlash(filepath.Join("build", "bin", binaryName))
o.options.WindowsFlags = ""
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 5bf6b2a9..eb4c38f7 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
@@ -1,7 +1,6 @@
{
"name": "{{.ProjectName}}",
"outputfilename": "{{.BinaryName}}",
- "assetdir": "frontend/dist",
"frontend:install": "npm install",
"frontend:build": "npm run build",
"wailsjsdir": "./frontend",
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 a4f2bc2d..b010f320 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
@@ -1,7 +1,6 @@
{
"name": "{{.ProjectName}}",
"outputfilename": "{{.BinaryName}}",
- "assetdir": "frontend/src",
"wailsjsdir": "./frontend",
"author": {
"name": "{{.AuthorName}}",
diff --git a/v2/internal/appng/app_dev.go b/v2/internal/appng/app_dev.go
index b232e21d..cf1bcdef 100644
--- a/v2/internal/appng/app_dev.go
+++ b/v2/internal/appng/app_dev.go
@@ -5,7 +5,10 @@ package appng
import (
"context"
+ "embed"
"flag"
+ "fmt"
+ iofs "io/fs"
"os"
"path/filepath"
@@ -91,12 +94,30 @@ func CreateApp(appoptions *options.App) (*App, error) {
}
}
+ if assetdir == "" {
+ // If no assetdir has been defined, let's try to infer it from the project root and the asset FS.
+ assetdir, err = tryInferAssetDirFromFS(appoptions.Assets)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if assetdir != "" {
+ // Let's override the assets to serve from on disk, if needed
+ absdir, err := filepath.Abs(assetdir)
+ if err != nil {
+ return nil, err
+ }
+
+ myLogger.Info("Serving assets from disk: %s", absdir)
+ appoptions.Assets = os.DirFS(absdir)
+
+ ctx = context.WithValue(ctx, "assetdir", assetdir)
+ }
+
if devServerURL != "" {
ctx = context.WithValue(ctx, "devserverurl", devServerURL)
}
- if assetdir != "" {
- ctx = context.WithValue(ctx, "assetdir", assetdir)
- }
if loglevel != "" {
level, err := pkglogger.StringToLogLevel(loglevel)
@@ -203,3 +224,32 @@ func generateBindings(bindings *binding.Bindings) error {
return nil
}
+
+func tryInferAssetDirFromFS(assets iofs.FS) (string, error) {
+ if _, isEmbedFs := assets.(embed.FS); !isEmbedFs {
+ // We only infer the assetdir for embed.FS assets
+ return "", nil
+ }
+
+ path, err := fs.FindPathToFile(assets, "index.html")
+ if err != nil {
+ return "", err
+ }
+
+ path, err = filepath.Abs(path)
+ if err != nil {
+ return "", err
+ }
+
+ if _, err := os.Stat(filepath.Join(path, "index.html")); err != nil {
+ if os.IsNotExist(err) {
+ err = fmt.Errorf(
+ "inferred assetdir '%s' does not exist or does not contain an 'index.html' file, "+
+ "please specify it with -assetdir or set it in wails.json",
+ path)
+ }
+ return "", err
+ }
+
+ return path, nil
+}
diff --git a/v2/internal/frontend/assetserver/assetserver_browser_dev.go b/v2/internal/frontend/assetserver/assetserver_browser_dev.go
index 296f98a7..93de7607 100644
--- a/v2/internal/frontend/assetserver/assetserver_browser_dev.go
+++ b/v2/internal/frontend/assetserver/assetserver_browser_dev.go
@@ -5,10 +5,13 @@ package assetserver
import (
"bytes"
+ "context"
+ "io/fs"
+ "strings"
+
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
- "github.com/wailsapp/wails/v2/pkg/options"
+ "github.com/wailsapp/wails/v2/internal/logger"
"golang.org/x/net/html"
- "path/filepath"
)
/*
@@ -18,35 +21,41 @@ It injects a websocket based IPC script into `index.html`.
*/
-import (
- "os"
-)
-
type BrowserAssetServer struct {
- runtimeJS []byte
- assetdir string
- appOptions *options.App
+ assets fs.FS
+ runtimeJS []byte
+ logger *logger.Logger
}
-func NewBrowserAssetServer(assetdir string, bindingsJSON string, appOptions *options.App) (*BrowserAssetServer, error) {
- result := &BrowserAssetServer{
- assetdir: assetdir,
- appOptions: appOptions,
+func NewBrowserAssetServer(ctx context.Context, assets fs.FS, bindingsJSON string) (*BrowserAssetServer, error) {
+ result := &BrowserAssetServer{}
+ _logger := ctx.Value("logger")
+ if _logger != nil {
+ result.logger = _logger.(*logger.Logger)
+ }
+
+ var err error
+ result.assets, err = prepareAssetsForServing(assets)
+ if err != nil {
+ return nil, err
}
var buffer bytes.Buffer
buffer.WriteString(`window.wailsbindings='` + bindingsJSON + `';` + "\n")
buffer.Write(runtime.RuntimeDesktopJS)
result.runtimeJS = buffer.Bytes()
+
return result, nil
}
-func (a *BrowserAssetServer) loadFileFromDisk(filename string) ([]byte, error) {
- return os.ReadFile(filepath.Join(a.assetdir, filename))
+func (d *BrowserAssetServer) LogDebug(message string, args ...interface{}) {
+ if d.logger != nil {
+ d.logger.Debug("[BrowserAssetServer] "+message, args...)
+ }
}
func (a *BrowserAssetServer) processIndexHTML() ([]byte, error) {
- indexHTML, err := a.loadFileFromDisk("index.html")
+ indexHTML, err := fs.ReadFile(a.assets, "index.html")
if err != nil {
return nil, err
}
@@ -96,7 +105,9 @@ func (a *BrowserAssetServer) Load(filename string) ([]byte, string, error) {
case "/wails/ipc.js":
content = runtime.WebsocketIPC
default:
- content, err = a.loadFileFromDisk(filename)
+ filename = strings.TrimPrefix(filename, "/")
+ a.LogDebug("Loading file: %s", filename)
+ content, err = fs.ReadFile(a.assets, filename)
}
if err != nil {
return nil, "", err
diff --git a/v2/internal/frontend/assetserver/assetserver_common.go b/v2/internal/frontend/assetserver/assetserver_common.go
new file mode 100644
index 00000000..d8ab4c9c
--- /dev/null
+++ b/v2/internal/frontend/assetserver/assetserver_common.go
@@ -0,0 +1,25 @@
+package assetserver
+
+import (
+ iofs "io/fs"
+ "path"
+
+ "github.com/wailsapp/wails/v2/internal/fs"
+)
+
+func prepareAssetsForServing(assets iofs.FS) (iofs.FS, error) {
+ if _, err := assets.Open("."); err != nil {
+ return nil, err
+ }
+
+ subDir, err := fs.FindPathToFile(assets, "index.html")
+ if err != nil {
+ return nil, err
+ }
+
+ assets, err = iofs.Sub(assets, path.Clean(subDir))
+ if err != nil {
+ return nil, err
+ }
+ return assets, nil
+}
diff --git a/v2/internal/frontend/assetserver/assetserver_desktop.go b/v2/internal/frontend/assetserver/assetserver_desktop.go
index 1ec4a753..6d4c15b2 100644
--- a/v2/internal/frontend/assetserver/assetserver_desktop.go
+++ b/v2/internal/frontend/assetserver/assetserver_desktop.go
@@ -3,26 +3,21 @@ package assetserver
import (
"bytes"
"context"
- "embed"
- "fmt"
- "github.com/leaanthony/debme"
- "github.com/leaanthony/slicer"
- "github.com/wailsapp/wails/v2/internal/frontend/runtime"
- "github.com/wailsapp/wails/v2/internal/logger"
"io/fs"
"log"
- "path/filepath"
"strings"
+
+ "github.com/wailsapp/wails/v2/internal/frontend/runtime"
+ "github.com/wailsapp/wails/v2/internal/logger"
)
type DesktopAssetServer struct {
- assets debme.Debme
+ assets fs.FS
runtimeJS []byte
- assetdir string
logger *logger.Logger
}
-func NewDesktopAssetServer(ctx context.Context, assets embed.FS, bindingsJSON string) (*DesktopAssetServer, error) {
+func NewDesktopAssetServer(ctx context.Context, assets fs.FS, bindingsJSON string) (*DesktopAssetServer, error) {
result := &DesktopAssetServer{}
_logger := ctx.Value("logger")
@@ -30,22 +25,18 @@ func NewDesktopAssetServer(ctx context.Context, assets embed.FS, bindingsJSON st
result.logger = _logger.(*logger.Logger)
}
- _assetdir := ctx.Value("assetdir")
- if _assetdir != nil {
- result.assetdir = _assetdir.(string)
- absdir, err := filepath.Abs(result.assetdir)
- if err != nil {
- return nil, err
- }
- result.LogDebug("Loading assets from: %s", absdir)
+ var err error
+ result.assets, err = prepareAssetsForServing(assets)
+ if err != nil {
+ return nil, err
}
var buffer bytes.Buffer
buffer.WriteString(`window.wailsbindings='` + bindingsJSON + `';` + "\n")
buffer.Write(runtime.RuntimeDesktopJS)
result.runtimeJS = buffer.Bytes()
- err := result.init(assets)
- return result, err
+
+ return result, nil
}
func (d *DesktopAssetServer) LogDebug(message string, args ...interface{}) {
@@ -54,63 +45,8 @@ func (d *DesktopAssetServer) LogDebug(message string, args ...interface{}) {
}
}
-func (d *DesktopAssetServer) SetAssetDir(assetdir string) {
- d.assetdir = assetdir
-}
-
-func PathToIndexHTML(assets embed.FS) (string, error) {
- stat, err := fs.Stat(assets, "index.html")
- if stat != nil {
- return ".", nil
- }
- var indexFiles slicer.StringSlicer
- err = fs.WalkDir(assets, ".", func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
- if strings.HasSuffix(path, "index.html") {
- indexFiles.Add(path)
- }
- return nil
- })
- if err != nil {
- return "", err
- }
-
- if indexFiles.Length() > 1 {
- return "", fmt.Errorf("multiple 'index.html' files found in assets")
- }
-
- path, _ := filepath.Split(indexFiles.AsSlice()[0])
- return path, nil
-}
-
-func processAssets(assets embed.FS) (debme.Debme, error) {
-
- result, err := debme.FS(assets, ".")
- if err != nil {
- return result, err
- }
- // Find index.html
- path, err := PathToIndexHTML(assets)
- if err != nil {
- return debme.Debme{}, err
- }
- return debme.FS(assets, path)
-}
-
-func (a *DesktopAssetServer) init(assets embed.FS) error {
-
- var err error
- a.assets, err = processAssets(assets)
- if err != nil {
- return err
- }
- return nil
-}
-
func (a *DesktopAssetServer) processIndexHTML() ([]byte, error) {
- indexHTML, err := a.ReadFile("index.html")
+ indexHTML, err := fs.ReadFile(a.assets, "index.html")
if err != nil {
return nil, err
}
@@ -146,7 +82,9 @@ func (a *DesktopAssetServer) Load(filename string) ([]byte, string, error) {
case "/wails/ipc.js":
content = runtime.DesktopIPC
default:
- content, err = a.ReadFile(filename)
+ filename = strings.TrimPrefix(filename, "/")
+ a.LogDebug("Loading file: %s", filename)
+ content, err = fs.ReadFile(a.assets, filename)
}
if err != nil {
return nil, "", err
diff --git a/v2/internal/frontend/assetserver/assetserver_desktop_dev.go b/v2/internal/frontend/assetserver/assetserver_desktop_dev.go
deleted file mode 100644
index 42726ae3..00000000
--- a/v2/internal/frontend/assetserver/assetserver_desktop_dev.go
+++ /dev/null
@@ -1,13 +0,0 @@
-//go:build dev
-
-package assetserver
-
-import (
- "os"
- "path/filepath"
-)
-
-func (a *DesktopAssetServer) ReadFile(filename string) ([]byte, error) {
- a.LogDebug("Loading file from disk: %s", filename)
- return os.ReadFile(filepath.Join(a.assetdir, filename))
-}
diff --git a/v2/internal/frontend/assetserver/assetserver_desktop_production.go b/v2/internal/frontend/assetserver/assetserver_desktop_production.go
deleted file mode 100644
index fb09ee1a..00000000
--- a/v2/internal/frontend/assetserver/assetserver_desktop_production.go
+++ /dev/null
@@ -1,7 +0,0 @@
-//go:build production
-
-package assetserver
-
-func (a *DesktopAssetServer) ReadFile(filename string) ([]byte, error) {
- return a.assets.ReadFile(filename)
-}
diff --git a/v2/internal/frontend/devserver/devserver.go b/v2/internal/frontend/devserver/devserver.go
index e73828c5..3dcb84c5 100644
--- a/v2/internal/frontend/devserver/devserver.go
+++ b/v2/internal/frontend/devserver/devserver.go
@@ -10,7 +10,6 @@ import (
"fmt"
"io/fs"
"log"
- "path/filepath"
"strings"
"sync"
"time"
@@ -50,6 +49,11 @@ func (d *DevWebServer) WindowReload() {
func (d *DevWebServer) Run(ctx context.Context) error {
d.ctx = ctx
+ assetdir, _ := ctx.Value("assetdir").(string)
+ d.server.Get("/wails/assetdir", func(fctx *fiber.Ctx) error {
+ return fctx.SendString(assetdir)
+ })
+
d.server.Get("/wails/reload", func(fctx *fiber.Ctx) error {
d.WindowReload()
d.desktopFrontend.WindowReload()
@@ -100,25 +104,14 @@ func (d *DevWebServer) Run(ctx context.Context) error {
_devServerURL := ctx.Value("devserverurl")
if _devServerURL == "http://localhost:34115" {
// Setup internal dev server
- _assetdir := ctx.Value("assetdir")
- if _assetdir == nil {
- return fmt.Errorf("no assetdir provided")
+ bindingsJSON, err := d.appBindings.ToJSON()
+ if err != nil {
+ log.Fatal(err)
}
- if _assetdir != nil {
- assetdir := _assetdir.(string)
- bindingsJSON, err := d.appBindings.ToJSON()
- if err != nil {
- log.Fatal(err)
- }
- d.assetServer, err = assetserver.NewBrowserAssetServer(assetdir, bindingsJSON, d.appoptions)
- if err != nil {
- log.Fatal(err)
- }
- absdir, err := filepath.Abs(assetdir)
- if err != nil {
- return err
- }
- d.LogDebug("Serving assets from: %s", absdir)
+
+ d.assetServer, err = assetserver.NewBrowserAssetServer(ctx, d.appoptions.Assets, bindingsJSON)
+ if err != nil {
+ log.Fatal(err)
}
d.server.Get("*", d.loadAsset)
diff --git a/v2/internal/fs/fs.go b/v2/internal/fs/fs.go
index 862e003c..0f6fbb7e 100644
--- a/v2/internal/fs/fs.go
+++ b/v2/internal/fs/fs.go
@@ -4,9 +4,11 @@ import (
"crypto/md5"
"fmt"
"io"
+ "io/fs"
"os"
"path/filepath"
"runtime"
+ "strings"
"unsafe"
"github.com/leaanthony/slicer"
@@ -394,3 +396,30 @@ func MoveDirExtended(src string, dst string, ignore []string) (err error) {
return
}
+
+func FindPathToFile(fsys fs.FS, file string) (string, error) {
+ stat, _ := fs.Stat(fsys, file)
+ if stat != nil {
+ return ".", nil
+ }
+ var indexFiles slicer.StringSlicer
+ err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if strings.HasSuffix(path, file) {
+ indexFiles.Add(path)
+ }
+ return nil
+ })
+ if err != nil {
+ return "", err
+ }
+
+ if indexFiles.Length() > 1 {
+ return "", fmt.Errorf("multiple '%s' files found in assets", file)
+ }
+
+ path, _ := filepath.Split(indexFiles.AsSlice()[0])
+ return path, nil
+}
diff --git a/v2/internal/project/project.go b/v2/internal/project/project.go
index 192f26e7..96d43358 100644
--- a/v2/internal/project/project.go
+++ b/v2/internal/project/project.go
@@ -15,6 +15,8 @@ type Project struct {
Name string `json:"name"`
AssetDirectory string `json:"assetdir"`
+ ReloadDirectories string `json:"reloaddirs"`
+
BuildCommand string `json:"frontend:build"`
InstallCommand string `json:"frontend:install"`
DevCommand string `json:"frontend:dev"`
diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go
index 717fd93d..db224a5a 100644
--- a/v2/pkg/options/options.go
+++ b/v2/pkg/options/options.go
@@ -2,11 +2,11 @@ package options
import (
"context"
- "embed"
- "github.com/wailsapp/wails/v2/pkg/options/linux"
+ "io/fs"
"log"
"runtime"
+ "github.com/wailsapp/wails/v2/pkg/options/linux"
"github.com/wailsapp/wails/v2/pkg/options/mac"
"github.com/wailsapp/wails/v2/pkg/options/windows"
@@ -41,7 +41,7 @@ type App struct {
HideWindowOnClose bool
AlwaysOnTop bool
RGBA *RGBA
- Assets embed.FS
+ Assets fs.FS
Menu *menu.Menu
Logger logger.Logger `json:"-"`
LogLevel logger.LogLevel