Skip to content

fix(build): copy frontend build output to embed target when frontend:dir is non-default#5251

Merged
leaanthony merged 3 commits into
masterfrom
v2-bugfix/5034-frontend-dir-build
May 31, 2026
Merged

fix(build): copy frontend build output to embed target when frontend:dir is non-default#5251
leaanthony merged 3 commits into
masterfrom
v2-bugfix/5034-frontend-dir-build

Conversation

@leaanthony

@leaanthony leaanthony commented Apr 26, 2026

Copy link
Copy Markdown
Member

Description

Fixes #5034

When frontend:dir in wails.json is set to a non-default path (e.g., ./jsfrontend), the build system correctly builds the frontend in that directory, but the //go:embed all:frontend/dist directive in main.go still references frontend/dist. This means the built assets (only a gitkeep placeholder) are not correctly included in the compiled binary, causing it to fail to start.

Changes

  • Added SyncFrontendDistToEmbedTarget function called after BuildFrontend
  • When the actual frontend directory differs from the default frontend/, discovers embed targets via staticanalysis.GetEmbedDetails and copies the built dist files to the embed target directory
  • No-op when using default frontend/ directory

Testing

  • Added tests in v2/test/5034/frontend_dir_test.go:
    • TestSyncFrontendDistToEmbedTarget: verifies files are copied correctly when frontend:dir is non-default
    • TestSyncFrontendDistNoOpWhenDefault: verifies no changes when using default dir
    • TestSyncFrontendDistNoOpWhenNoDistInEmbed: verifies no errors when no dist embed dirs found
    • TestEmbedDiscoveryInTempDir: verifies embed discovery works in temp dirs

Limitations

This fix does NOT address the case where frontend:dir points outside the project directory (e.g., "../frontend"), as Go's //go:embed directive cannot reference paths outside the module. Users in that situation need to manually update their embed directive.

Summary by CodeRabbit

  • New Features

    • Enhanced the build process to automatically synchronize custom frontend build output into the proper directory structure during compilation, supporting custom frontend directory configurations.
  • Tests

    • Added comprehensive end-to-end tests for frontend build output synchronization, verifying correct directory placement, cleanup behavior, and edge cases with custom frontend directories.

…dir is non-default

When the frontend directory is configured via frontend:dir in wails.json
to a non-default path (e.g. ./jsfrontend), the build system correctly
builds the frontend in that directory but the Go embed directive still
references frontend/dist. This means the built assets are not included
in the compiled binary.

After BuildFrontend, if the actual frontend directory differs from the
default frontend/ directory, the built dist files are copied to the
embed target directory discovered via static analysis of //go:embed
directives.

Fixes #5034
@coderabbitai

coderabbitai Bot commented Apr 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 468561a2-7186-4d4d-a291-8767f6dc0397

📥 Commits

Reviewing files that changed from the base of the PR and between 230a627 and b5b5fe1.

📒 Files selected for processing (2)
  • v2/pkg/commands/build/build.go
  • v2/test/5034/frontend_dir_test.go

Walkthrough

Adds SyncFrontendDistToEmbedTarget and integrates it into Build: it detects embed target directories via staticanalysis, copies a custom frontend's built dist into those embed-target dist folders, and returns a deferred cleanup that removes copied files and restores .gitkeep placeholders.

Changes

Frontend Dist Synchronization

Layer / File(s) Summary
Sync function implementation and build integration
v2/pkg/commands/build/build.go
SyncFrontendDistToEmbedTarget discovers embed targets via staticanalysis.GetEmbedDetails, conditionally copies a custom frontend dist into embed-target dist directories, returns a cleanup that removes copies and recreates .gitkeep, and is invoked from Build with deferred cleanup.
Sync and cleanup verification tests
v2/test/5034/frontend_dir_test.go
Tests verify embed discovery, copied file contents and .gitkeep removal, cleanup restoration of .gitkeep, and no-op behavior when using the default frontend directory or when the source dist is missing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • wailsapp/wails#3887: Related PR that updates templates to embed all:frontend/dist, which interacts with the embed targets prepared by this sync logic.

Suggested labels

Ready For Testing

Suggested reviewers

  • fbbdev

Poem

🐰 I hopped through dirs both near and far,
Copied dist to embeds — a careful spar,
I cleaned up footprints, left .gitkeep to stay,
Build hums along, assets snug in play,
A tiny rabbit clap for the build today!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v2-bugfix/5034-frontend-dir-build

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@leaanthony

Copy link
Copy Markdown
Member Author

🤖 PR Triage Review

Accepted

This PR fixes a build issue where frontend assets aren't copied to the embed target when using a custom frontend:dir. Important fix for users with non-standard project layouts.

Changes: 234 additions, 2 files changed

Platform: All (v2-only, build system)

Next Steps: Dispatching for testing on all platforms.


Reviewed by Wails PR Reviewer Bot

@leaanthony

Copy link
Copy Markdown
Member Author

test

@leaanthony

Copy link
Copy Markdown
Member Author

Tested on macOS (darwin/arm64) — verdict: ✓ pass

  • Commit: cc3095dca1
  • Build: 16.6s successful
  • Unit tests: 4/4 passing
  • Visual smoke: ✓ wails build with custom frontend:dir synced assets from webapp/dist/ to frontend/dist/ (the embed target), replacing a placeholder with the full Vite build output
Unit test output
=== RUN   TestEmbedDiscoveryInTempDir      --- PASS (0.16s)
=== RUN   TestSyncFrontendDistToEmbedTarget --- PASS (0.20s)
=== RUN   TestSyncFrontendDistNoOpWhenDefault --- PASS (0.00s)
=== RUN   TestSyncFrontendDistNoOpWhenNoDistInEmbed --- PASS (0.07s)
PASS
ok  github.com/wailsapp/wails/v2/test/5034  0.451s

SyncFrontendDistToEmbedTarget now returns a cleanup func that removes
the copied assets and restores a .gitkeep placeholder after the build
completes, keeping the working tree clean. The cleanup runs via defer
so it fires whether the build succeeds or fails.
@leaanthony

Copy link
Copy Markdown
Member Author

Added cleanup in 5945771SyncFrontendDistToEmbedTarget now returns a func() that the call site defers. After the build (success or failure), it removes the copied assets and writes a fresh .gitkeep so the working tree is clean.

Behaviour:

  • Custom frontend:dir + non-default embed target → assets copied in, build runs, copied assets removed, .gitkeep restored
  • Default frontend dir → noop, no-op cleanup returned
  • Build fails → cleanup still runs via defer, directory is restored

New test: TestSyncFrontendDistCleanupRestoresGitkeep verifies the cleanup leaves only .gitkeep in frontend/dist.

@leaanthony leaanthony marked this pull request as ready for review May 31, 2026 12:51
Copilot AI review requested due to automatic review settings May 31, 2026 12:51
@leaanthony leaanthony merged commit f83493c into master May 31, 2026
12 of 16 checks passed
@leaanthony leaanthony deleted the v2-bugfix/5034-frontend-dir-build branch May 31, 2026 12:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v2] Fully built apps fail to run when frontend:dir is not default

2 participants