Skip to content

Commit c7a8ee6

Browse files
committed
Added 1.16+ embed mode
1 parent 1b1e080 commit c7a8ee6

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
run: pkged.go
2-
go run main.go pkged.go -mode embed
2+
go run main.go pkged.go -mode pkger
33

44
pkged.go: react-app/build
55
pkger -o ./ -include /react-app/build

README.md

+27-5
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ Usage of go-react:
1717
-dir string
1818
Directory where the static built app resides (default "./react-app/build/")
1919
-embed string
20-
Directory where the static built embeded app resides (default "/react-app/build/")
20+
Directory where the static built embeded app resides (1.16+) (default "react-app/build")
2121
-listen string
2222
Listen on address (default ":8080")
2323
-mode string
24-
Mode to serve REACT site: proxy, dir, embed (default "proxy")
24+
Mode to serve REACT site: proxy, dir, pkger, embed (default "proxy")
25+
-pkger string
26+
Directory where the static built embeded app resides (default "/react-app/build/")
2527
-proxy string
2628
Address to proxy requests to (default "http://localhost:3000/")
2729
```
@@ -66,7 +68,7 @@ go run main.go -mode dir
6668
```
6769

6870

69-
### Embed mode
71+
### Packaged mode (pre 1.16)
7072

7173
This method will build the react code into a deployment/production version, then embed it in the binary. This means you only need to produce a single binary for distribution without needing to deploy the react code as well. I find this very useful for programs that need a user interface but dont want the heft of a full update system.
7274

@@ -93,11 +95,31 @@ Build and run the binary
9395
```
9496
go build -o go-react main.go pkged.go
9597
96-
./go-react -mode embed
98+
./go-react -mode pkger
9799
98100
```
99101

100102
Alternatively, the Makefile has all these steps:
101103
```
102104
make run
103-
```
105+
```
106+
107+
### Embed mode (1.16+)
108+
109+
This provides the same methods as the packager method, but uses the new 1.16+ interface.
110+
111+
First, build the react code into a deployment/production version
112+
113+
```
114+
cd react-app/
115+
npm build
116+
```
117+
118+
Next, run the code. The files are automatically embeded.
119+
120+
```
121+
go run main.go -mode embed
122+
```
123+
124+
125+

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module github.com/bmurray/go-react
22

3-
go 1.15
3+
go 1.16
44

55
require github.com/markbates/pkger v0.17.1

main.go

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package main
22

33
import (
4+
"embed"
45
"encoding/json"
56
"flag"
7+
"io/fs"
68
"log"
79
"net/http"
810
"net/http/httputil"
@@ -12,14 +14,19 @@ import (
1214
"github.com/markbates/pkger"
1315
)
1416

17+
//go:embed react-app/build
18+
var embeded embed.FS
19+
1520
func main() {
16-
mode := flag.String("mode", "proxy", "Mode to serve REACT site: proxy, dir, embed")
21+
mode := flag.String("mode", "proxy", "Mode to serve REACT site: proxy, dir, pkger, embed ")
1722
// Proxy mode proxies all other connections to the npm server
1823
proxy := flag.String("proxy", "http://localhost:3000/", "Address to proxy requests to")
1924
// Dir follows general filesystem pathing rules
2025
dir := flag.String("dir", "./react-app/build/", "Directory where the static built app resides")
2126
// Embed needs to be absolute, based on the arguments of pkger. See Makefile
22-
embed := flag.String("embed", "/react-app/build/", "Directory where the static built embeded app resides")
27+
packaged := flag.String("pkger", "/react-app/build/", "Directory where the static built embeded app resides")
28+
// Embed uses the new 1.16 embed functions to offer what pkger does
29+
embed := flag.String("embed", "react-app/build", "Directory where the static built embeded app resides (1.16+)")
2330
listen := flag.String("listen", ":8080", "Listen on address")
2431
flag.Parse()
2532

@@ -40,9 +47,17 @@ func main() {
4047
case "dir":
4148
// Dir mode is useful if you build your react app but don't want to embed it in the binary, such as Docker deploys
4249
mux.Handle("/", http.FileServer(EmbedDir{http.Dir(*dir)}))
50+
case "pkger":
51+
// Pkger mode serves files that are embedded in the binary. Very useful for one-file distribution
52+
mux.Handle("/", http.FileServer(EmbedDir{pkger.Dir(*packaged)}))
4353
case "embed":
44-
// Embed mode serves files that are embedded in the binary. Very useful for one-file distribution
45-
mux.Handle("/", http.FileServer(EmbedDir{pkger.Dir(*embed)}))
54+
// Embed uses the new 1.16+ Embed functionality
55+
filesystem := fs.FS(embeded)
56+
static, err := fs.Sub(filesystem, *embed)
57+
if err != nil {
58+
log.Fatal("Cannot open filesystem", err)
59+
}
60+
mux.Handle("/", http.FileServer(EmbedDir{http.FS(static)}))
4661
default:
4762
// Any other mode would assume you have a reverse proxy, like nginx, that filters traffic
4863
log.Println("No react mode; this only works if you have a frontend reverse proxy")

0 commit comments

Comments
 (0)