先决条件
1.18.31.22.18v16.15.1
创建我们的 Go 项目
首先我们要创建我们的 Go 项目
mkdir go-react-demo
cd go-react-demo
touch main.go
进入全屏模式 退出全屏模式
然后,我们要安装Echo这是一个 Web 框架(类似于 Gin、Fiber 等)
go get github.com/labstack/echo/v4
进入全屏模式 退出全屏模式
使用 echo 创建基本 API 路由端点
main.go
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/api", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":8080"))
}
进入全屏模式 退出全屏模式
GEThttp://localhost:8080/apiHello, World!
curl http:localhost:8080/api # <-- Should output "Hello, World!"
进入全屏模式 退出全屏模式
如果一切正常,接下来我们将使用 Vite 创建我们的 React 应用程序
使用/ Vite 创建你的 React 应用程序
确保您位于根项目目录中,然后运行:
yarn create vite
# Set the "project name" to "web"
# Set the "web framework" to "react" & "react-ts"
进入全屏模式 退出全屏模式
Vite
cd web
yarn install
进入全屏模式 退出全屏模式
package.json
package.jsondevvitevite
"scripts": {
"dev": "tsc && vite build --watch", <-- Change dev script to this
"build": "tsc && vite build",
"preview": "vite preview"
},
进入全屏模式 退出全屏模式
devtsc && vite build --watchvite
webyarn devdist
# In go-react-demo/web
yarn run dev
进入全屏模式 退出全屏模式
此时我们的文件夹结构将如下所示:
go-react-demo/
├─ web/
│ ├─ dist/
│ ├─ public/
│ ├─ src/
| ├─ ...
├─ main.go
├─ go.sum
├─ go.mod
进入全屏模式 退出全屏模式
使用 Echo 服务我们的静态文件
webweb.go
// In go-react-demo/web/web.go
package web
import (
"embed"
"github.com/labstack/echo/v4"
)
var (
//go:embed all:dist
dist embed.FS
//go:embed dist/index.html
indexHTML embed.FS
distDirFS = echo.MustSubFS(dist, "dist")
distIndexHtml = echo.MustSubFS(indexHTML, "dist")
)
func RegisterHandlers(e *echo.Echo) {
e.FileFS("/", "index.html", distIndexHtml)
e.StaticFS("/", distDirFS)
}
进入全屏模式 退出全屏模式
/web/index.html
RegisterHandlersmain.go
main.gowebRegisterHandlers
package main
import (
"net/http"
"go-react-demo/web" # <--- INCLUDE THIS
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
web.RegisterHandlers(e) # <-- INCLUDE THIS
e.GET("/api", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello world!")
})
e.Logger.Fatal(e.Start(":8080"))
}
进入全屏模式 退出全屏模式
现在让我们测试 go 服务器,看看它是否正确地为我们的 react 应用程序的静态资产提供服务。转到项目的根目录并运行:
go run main.go
进入全屏模式 退出全屏模式
现在,如果您在浏览器中访问http://localhost:8080,您应该会看到默认的 vite React 应用程序。
从 React 内部向 Go API 服务器发出请求
GET
// In go-react-demo/web/src/App.tsx
import { useState, useEffect } from "react";
import "./App.css";
function App() {
const [data, setData] = useState("");
useEffect(() => {
const fetchData = async () => {
const response = await fetch("http://localhost:8080/api");
const data = await response.text();
setData(data);
};
fetchData().catch((err) => console.log(err));
}, []);
return (
<div className="App">
<h1>{data}</h1>
</div>
);
}
export default App;
进入全屏模式 退出全屏模式
现在我们需要重新生成 React 静态文件,因为我们已经进行了更改。
# assuming you're currently at the rootDirectory (go-react-demo)
cd web && yarn run dev # Generates the new static assets
进入全屏模式 退出全屏模式
然后我们需要运行 go server 来提供文件
cd .. && go run main.go
进入全屏模式 退出全屏模式
如果我们访问http://localhost:8080,你应该会看到来自 Go API 服务器的“Hello world”
真是糟糕的开发体验
我敢肯定你注意到,总是运行两个具有不同进程的终端是一种非常糟糕的开发体验,不要担心我有解决方案!
airnodemongoairgo run main.go
air
go install github.com/cosmtrek/air@latest
进入全屏模式 退出全屏模式
air
#You should be in the root directory of the go-react-demo project
air init # Should output a `.air.toml`
进入全屏模式 退出全屏模式
wsldev.sh
touch dev.sh # creates the file
进入全屏模式 退出全屏模式
dev.sh
#!/bin/sh
cd web && yarn dev & air && fg
进入全屏模式 退出全屏模式
这将在一个终端中同时运行 go api 服务器和 vite 构建服务器
编译二进制文件
现在,关键时刻:编译包含 React 应用程序的二进制文件只需运行
go build main.go
进入全屏模式 退出全屏模式
如果您尝试从 WSL 构建 Windows 二进制文件:
env GOOS=windows GOARCH=amd64 go build main.go
# You may have a different $GOARCH so please do some research
进入全屏模式 退出全屏模式