6 Commits

Author SHA1 Message Date
0ccffe88ce Update drone CI upload backend program
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 21:13:10 +08:00
a7230519ff Update: Makefile since we dont use sqlite3 and CGO 2022-12-17 21:13:10 +08:00
21b2098c78 Add: embed web files 2022-12-17 21:13:09 +08:00
d52c64d25a Fix: web css modules tree shaking 2022-12-17 21:13:09 +08:00
bec2d6538f add drone pipeline 2022-12-17 21:13:09 +08:00
aa2377df7f Replace webpack with only esbuild, replace react with preact
reduce node_modules size to only 18M

reduce js file bundle to 20%
2022-12-17 21:12:41 +08:00
12 changed files with 134 additions and 92 deletions

View File

@@ -2,17 +2,33 @@ kind: pipeline
type: docker type: docker
name: default name: default
clone:
depth: 1
steps: steps:
- name: frontend-web - name: frontend-web
image: node:19 image: node:19
commands: commands:
- cd web - cd web
- npm install - npm install
- npm run build - npm run build
- name: release - name: backend
image: plugins/gitea-release image: golang:1.19
commands:
- go build -v .
environment:
CGO_ENABLED: 0
GOPROXY: goproxy.cn
- name: upload
image: plugins/s3-sync
settings: settings:
api_key: da966507c259aa32ccc2d434e930af4a580de785 bucket: msw-artifacts-public
base_url: https://yongyuancv.cn/git/ region: ap-southeast-1
files: dist/* access_key:
from_secret: access_key
secret_key:
from_secret: secret_key
source: msw-open-music
target: /msw-open-music/${DRONE_COMMIT}/

View File

@@ -4,7 +4,7 @@ web:
cd web && npm run build cd web && npm run build
linux: linux:
go build -v -ldflags '-linkmode=external -extldflags=-static' -tags sqlite_omit_load_extension,netgo CGO_ENABLED=0 go build -v -ldflags '-extldflags=-static'
windows: windows:
CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -v CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -v

14
main.go
View File

@@ -1,8 +1,10 @@
package main package main
import ( import (
"embed"
"encoding/json" "encoding/json"
"flag" "flag"
"io/fs"
"log" "log"
"msw-open-music/pkg/api" "msw-open-music/pkg/api"
"msw-open-music/pkg/commonconfig" "msw-open-music/pkg/commonconfig"
@@ -15,11 +17,21 @@ func init() {
flag.StringVar(&ConfigFilePath, "config", "config.json", "backend config file path") flag.StringVar(&ConfigFilePath, "config", "config.json", "backend config file path")
} }
//go:embed web/build
var WEBFILES embed.FS
func main() { func main() {
var err error var err error
flag.Parse() flag.Parse()
config := commonconfig.Config{} WEBFS, err := fs.Sub(WEBFILES, "web/build")
if err != nil {
log.Fatal(err)
}
config := commonconfig.Config{
WEBFS: WEBFS,
}
configFile, err := os.Open(ConfigFilePath) configFile, err := os.Open(ConfigFilePath)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@@ -1,11 +1,12 @@
package api package api
import ( import (
"github.com/gorilla/sessions"
"msw-open-music/pkg/commonconfig" "msw-open-music/pkg/commonconfig"
"msw-open-music/pkg/database" "msw-open-music/pkg/database"
"msw-open-music/pkg/tmpfs" "msw-open-music/pkg/tmpfs"
"net/http" "net/http"
"github.com/gorilla/sessions"
) )
type API struct { type API struct {
@@ -103,7 +104,7 @@ func NewAPI(config commonconfig.Config) (*API, error) {
apiMux.HandleFunc("/reset", api.HandleReset) apiMux.HandleFunc("/reset", api.HandleReset)
mux.Handle("/api/v1/", http.StripPrefix("/api/v1", api.PermissionMiddleware(apiMux))) mux.Handle("/api/v1/", http.StripPrefix("/api/v1", api.PermissionMiddleware(apiMux)))
mux.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("web/build")))) mux.Handle("/", http.StripPrefix("/", http.FileServer(http.FS(config.WEBFS))))
return api, nil return api, nil
} }

View File

@@ -1,8 +1,11 @@
package commonconfig package commonconfig
import "io/fs"
type Config struct { type Config struct {
APIConfig APIConfig `json:"api"` APIConfig APIConfig `json:"api"`
TmpfsConfig TmpfsConfig `json:"tmpfs"` TmpfsConfig TmpfsConfig `json:"tmpfs"`
WEBFS fs.FS
} }
type APIConfig struct { type APIConfig struct {

20
web/build.js Normal file
View File

@@ -0,0 +1,20 @@
const fs = require("fs");
const esbuild = require("esbuild");
(async () => {
fs.rmSync("build", { recursive: true, force: true });
fs.cpSync("public", "build", { recursive: true });
const result = await esbuild.build({
entryPoints: ["src/index.jsx"],
bundle: true,
outfile: "build/msw-open-music.js",
sourcemap: true,
minify: true,
metafile: true,
});
const text = await esbuild.analyzeMetafile(result.metafile);
console.log(text);
console.log("Build done, output files udner ./build directory");
})();

View File

@@ -1,6 +0,0 @@
rm -rf build
cp -raf public build
./node_modules/.bin/esbuild src/index.jsx --bundle --outfile=build/msw-open-music.js --alias:react=preact/compat --alias:react-dom=preact/compat --minify --analyze
cat public/index.html | sed "s/%PUBLIC_URL%/$PUBLIC_URL/" > build/index.html
echo "Build done, output files under ./build directory"

View File

@@ -9,6 +9,6 @@
"water.css": "^2.1.1" "water.css": "^2.1.1"
}, },
"scripts": { "scripts": {
"build": "bash ./build.sh" "build": "node build.js"
} }
} }

View File

@@ -2,18 +2,18 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.png" /> <link rel="icon" href="./favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Personal music streaming platform" /> <meta name="description" content="Personal music streaming platform" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/favicon.png" /> <link rel="apple-touch-icon" href="./favicon.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="./manifest.json" />
<link rel="stylesheet" href="%PUBLIC_URL%/msw-open-music.css" /> <link rel="stylesheet" href="./msw-open-music.css" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<title>MSW Open Music</title> <title>MSW Open Music</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<script type="module" src="%PUBLIC_URL%/msw-open-music.js"></script> <script type="module" src="./msw-open-music.js"></script>
</body> </body>
</html> </html>

View File

@@ -1,16 +1,3 @@
html {
font-size: 1em;
}
body {
margin: auto;
padding-top: 1rem;
max-width: unset;
min-height: 100vh;
}
#root {
display: flex;
justify-content: center;
}
.base { .base {
display: grid; display: grid;
grid-row-gap: 1em; grid-row-gap: 1em;
@@ -48,54 +35,10 @@ body {
color: rgb(229, 232, 245); color: rgb(229, 232, 245);
padding: 1em; padding: 1em;
} }
a.unset {
color: unset;
text-decoration: unset;
}
a.active {
color: deeppink;
background-color: lightgray;
border-radius: 0.39em 0.39em 0 0;
}
.audio-player { .audio-player {
height: 39px; height: 39px;
width: 100%; width: 100%;
} }
td.clickable {
cursor: pointer;
}
div.clickable {
cursor: pointer;
}
div.page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div.search_toolbar {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-end;
width: 100%;
}
div.feedback {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
button.refresh {
width: 100%;
}
td,
th {
padding-bottom: 0.5em;
padding-top: 0.5em;
}
dialog {
border: solid;
}
.player-options { .player-options {
display: flex; display: flex;
} }

View File

@@ -1,13 +1,66 @@
#root {
display: flex;
justify-content: center;
}
html {
font-size: 1em;
}
body { body {
margin: 0; margin: auto;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', padding-top: 1rem;
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', max-width: none;
min-height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif; sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
code { code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace; monospace;
} }
a.unset {
color: unset;
text-decoration: unset;
}
a.active {
color: deeppink;
background-color: lightgray;
border-radius: 0.39em 0.39em 0 0;
}
td.clickable {
cursor: pointer;
}
div.clickable {
cursor: pointer;
}
div.page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
div.search_toolbar {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-end;
width: 100%;
}
div.feedback {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
button.refresh {
width: 100%;
}
td,
th {
padding-bottom: 0.5em;
padding-top: 0.5em;
}
dialog {
border: solid;
}

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import './index.css';
import 'water.css'; import 'water.css';
import './index.css';
import App from './App'; import App from './App';
ReactDOM.render( ReactDOM.render(