serve frontend + backend as a one binary
This commit is contained in:
parent
5954ec2501
commit
e378db58b8
@ -7,13 +7,15 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"gitserver.in/patialtech/mux"
|
||||
"gitserver.in/patialtech/mux/middleware"
|
||||
"gitserver.in/patialtech/rano/cmd/server/handler"
|
||||
"gitserver.in/patialtech/rano/bin/server/handler"
|
||||
"gitserver.in/patialtech/rano/config"
|
||||
"gitserver.in/patialtech/rano/graph"
|
||||
"gitserver.in/patialtech/rano/util/logger"
|
||||
"gitserver.in/patialtech/rano/web"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -24,6 +26,7 @@ func main() {
|
||||
// CORS
|
||||
r.Use(middleware.CORS(middleware.CORSOption{
|
||||
AllowedHeaders: []string{"Content-Type"},
|
||||
AllowedOrigins: []string{config.Read().WebURL},
|
||||
MaxAge: 60,
|
||||
}))
|
||||
// Secure Headers
|
||||
@ -40,7 +43,37 @@ func main() {
|
||||
|
||||
// catch all
|
||||
r.GET("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("hello there"))
|
||||
var (
|
||||
resourcePath string
|
||||
path = r.URL.Path
|
||||
)
|
||||
|
||||
if strings.HasPrefix(path, "/_app") {
|
||||
resourcePath = "public/build" + path
|
||||
} else if strings.HasSuffix(path, ".png") ||
|
||||
strings.HasSuffix(path, ".ico") ||
|
||||
strings.HasSuffix(path, ".svg") ||
|
||||
strings.HasSuffix(path, "robot.txt") ||
|
||||
strings.HasSuffix(path, "site.webmanifest") {
|
||||
resourcePath = "public" + path
|
||||
} else {
|
||||
resourcePath = "public/build/fallback.html"
|
||||
}
|
||||
|
||||
if b, err := web.Public.ReadFile(resourcePath); err != nil {
|
||||
_, _ = w.Write([]byte("hello there"))
|
||||
} else {
|
||||
if strings.HasSuffix(path, ".js") {
|
||||
w.Header().Set("Content-Type", "text/javascript")
|
||||
} else if strings.HasSuffix(path, ".css") {
|
||||
w.Header().Set("Content-Type", "text/css")
|
||||
} else {
|
||||
w.Header().Set("Content-Type", http.DetectContentType(b))
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(b)
|
||||
}
|
||||
})
|
||||
|
||||
r.Serve(func(srv *http.Server) error {
|
@ -19,16 +19,12 @@ import (
|
||||
const (
|
||||
// projDir need to be same as project code root dir name
|
||||
projDir = "rano"
|
||||
EnvDev = "development"
|
||||
EnvProd = "production"
|
||||
EnvStage = "staging"
|
||||
|
||||
AuthUserCtxKey = "AuthUser"
|
||||
)
|
||||
|
||||
var (
|
||||
conf *Config
|
||||
AppEnv Env = EnvDev
|
||||
AppEnv = "development" // production | staging
|
||||
)
|
||||
|
||||
type (
|
||||
@ -47,7 +43,7 @@ type (
|
||||
|
||||
func init() {
|
||||
var base string
|
||||
if AppEnv == EnvDev {
|
||||
if AppEnv == "development" { // AppEnv will be changed on build time using ldflags -X
|
||||
wd, _ := os.Getwd()
|
||||
idx := strings.Index(wd, projDir)
|
||||
if idx > -1 {
|
||||
@ -57,6 +53,8 @@ func init() {
|
||||
base, _ = os.Executable()
|
||||
}
|
||||
|
||||
logger.Info("*** %s", AppEnv)
|
||||
|
||||
envVar, err := dotenv.Read(base, fmt.Sprintf(".env.%s", AppEnv))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -1,7 +1,5 @@
|
||||
import path from 'node:path';
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
|
||||
const webDir = path.resolve('.', 'web');
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
@ -9,16 +7,15 @@ const config = {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter(),
|
||||
files: {
|
||||
appTemplate: path.resolve(webDir, 'app.html'),
|
||||
routes: path.resolve(webDir, 'routes'),
|
||||
lib: path.resolve(webDir, 'lib'),
|
||||
assets: path.resolve(webDir, 'public')
|
||||
appTemplate: "web/app.html" ,
|
||||
routes: "web/routes",
|
||||
lib: "web/lib",
|
||||
assets: "public/lib"
|
||||
},
|
||||
alias: {
|
||||
$image: path.resolve(webDir, 'assets', 'image'),
|
||||
$svg: path.resolve(webDir, 'assets', 'svg')
|
||||
$image: "web/assets/image",
|
||||
$svg: "web/assets/svg"
|
||||
},
|
||||
paths: {
|
||||
assets: process.env.ASSETS_HOST ?? ''
|
||||
@ -28,8 +25,8 @@ const config = {
|
||||
pollInterval: 1000 * 60 * 1 // 5 minutes
|
||||
},
|
||||
adapter: adapter({
|
||||
pages: path.resolve(webDir, 'public', 'build'),
|
||||
assets: path.resolve(webDir, 'public', 'build'),
|
||||
pages: "web/public/build",
|
||||
assets: "web/public/build",
|
||||
fallback: 'fallback.html',
|
||||
strict: true
|
||||
})
|
||||
|
28
taskfile.yml
28
taskfile.yml
@ -1,9 +1,12 @@
|
||||
version: '3'
|
||||
|
||||
dotenv: ['.env.{{.ENV}}']
|
||||
|
||||
env:
|
||||
ENV: development
|
||||
|
||||
dotenv: ['.env.{{.ENV}}']
|
||||
vars:
|
||||
MOD_NAME: gitserver.in/patialtech/rano
|
||||
|
||||
tasks:
|
||||
install:
|
||||
@ -14,7 +17,7 @@ tasks:
|
||||
start-graph:
|
||||
desc: run graph server
|
||||
cmds:
|
||||
- cmd: go run ./cmd/server
|
||||
- cmd: go run ./bin/server
|
||||
|
||||
start-web:
|
||||
desc: run web in dev mode
|
||||
@ -44,11 +47,11 @@ tasks:
|
||||
- cmd: deno task codegen
|
||||
|
||||
ent-new:
|
||||
desc: create new db Emtity
|
||||
cmd: cd ./db && go run -mod=mod entgo.io/ent/cmd/ent new {{.name}}
|
||||
desc: create new db Entity
|
||||
cmd: cd ./db && go run -mod=mod entry.io/ent/cmd/ent new {{.name}}
|
||||
|
||||
ent-gen:
|
||||
desc: genertate from ent schema
|
||||
desc: generate from ent schema
|
||||
cmds:
|
||||
- go generate ./db/ent
|
||||
|
||||
@ -61,4 +64,17 @@ tasks:
|
||||
desc: apply automatically migration using Ent schema
|
||||
cmds:
|
||||
- task: ent-gen
|
||||
- go run ./cmd/migrate-up
|
||||
- go run ./bin/migrate-up
|
||||
|
||||
build-web-prod:
|
||||
desc: apply automatically migration using Ent schema
|
||||
cmds:
|
||||
- deno task build
|
||||
env:
|
||||
ASSETS_HOST:
|
||||
|
||||
build-prod:
|
||||
desc: apply automatically migration using Ent schema
|
||||
cmds:
|
||||
- task: build-web-prod
|
||||
- CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -ldflags "-X '{{.MOD_NAME}}/config.AppEnv=production'" -o ./server ./bin/server
|
BIN
web/public/android-chrome-192x192.png
Normal file
BIN
web/public/android-chrome-192x192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
BIN
web/public/android-chrome-512x512.png
Normal file
BIN
web/public/android-chrome-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
web/public/apple-touch-icon.png
Normal file
BIN
web/public/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
BIN
web/public/favicon-16x16.png
Normal file
BIN
web/public/favicon-16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 262 B |
BIN
web/public/favicon-32x32.png
Normal file
BIN
web/public/favicon-32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 548 B |
BIN
web/public/favicon.ico
Normal file
BIN
web/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
11
web/public/site.webmanifest
Normal file
11
web/public/site.webmanifest
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"icons": [
|
||||
{ "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
|
||||
{ "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
6
web/web.go
Normal file
6
web/web.go
Normal file
@ -0,0 +1,6 @@
|
||||
package web
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed public public/build/_app
|
||||
var Public embed.FS
|
Loading…
Reference in New Issue
Block a user