支持非根目录部署

This commit is contained in:
whyour 2023-05-19 01:10:33 +08:00
parent 1377fe31aa
commit 490bdc15f6
13 changed files with 88 additions and 55 deletions

View File

@ -1,6 +1,7 @@
import { defineConfig } from '@umijs/max';
const CompressionPlugin = require('compression-webpack-plugin');
const baseUrl = process.env.QlBaseUrl || '/';
export default defineConfig({
hash: true,
antd: {},
@ -12,15 +13,16 @@ export default defineConfig({
},
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
proxy: {
'/api/public': {
[`${baseUrl}api/public`]: {
target: 'http://127.0.0.1:5400/',
changeOrigin: true,
pathRewrite: { '^/api/public': '/api/' },
pathRewrite: { [`^${baseUrl}api/public`]: '/api' },
},
'/api': {
[`${baseUrl}api`]: {
target: 'http://127.0.0.1:5600/',
changeOrigin: true,
ws: true,
pathRewrite: { [`^${baseUrl}api`]: '/api' },
},
},
chainWebpack: ((config: any) => {
@ -38,6 +40,7 @@ export default defineConfig({
'react-dom': 'window.ReactDOM',
},
headScripts: [
'./api/env.js',
'https://gw.alipayobjects.com/os/lib/react/18.2.0/umd/react.production.min.js',
'https://gw.alipayobjects.com/os/lib/react-dom/18.2.0/umd/react-dom.production.min.js',
],

View File

@ -92,6 +92,11 @@ export default {
'/api/system',
'/api/user/init',
'/api/user/notification/init',
'/open/user/login',
'/open/user/two-factor/login',
'/open/system',
'/open/user/init',
'/open/user/notification/init',
],
versionFile,
lastVersionFile,

20
back/config/serverEnv.ts Normal file
View File

@ -0,0 +1,20 @@
import { Request, Response } from 'express';
import { pick } from 'lodash';
let pickedEnv: Record<string, string>;
function getPickedEnv() {
if (pickedEnv) return pickedEnv;
const picked = pick(process.env, ['QlBaseUrl']);
pickedEnv = picked as Record<string, string>;
return picked;
}
export function serveEnv(_req: Request, res: Response) {
res.type('.js');
res.send(
Object.entries(getPickedEnv())
.map(([k, v]) => `window.__ENV__${k}=${JSON.stringify(v)};`)
.join('\n'),
);
}

View File

@ -16,10 +16,12 @@ import { EnvModel } from '../data/env';
import { errors } from 'celebrate';
import path from 'path';
import { createProxyMiddleware } from 'http-proxy-middleware';
import { serveEnv } from '../config/serverEnv';
export default ({ app }: { app: Application }) => {
app.enable('trust proxy');
app.use(cors());
app.get(`${config.api.prefix}/env.js`, serveEnv);
app.use(`${config.api.prefix}/static`, express.static(config.uploadPath));
app.use(
@ -31,27 +33,6 @@ export default ({ app }: { app: Application }) => {
}),
);
app.use((req, res, next) => {
if (req.path.startsWith('/api') || req.path.startsWith('/open')) {
next();
} else {
return handler(req, res, {
public: path.join(config.rootPath, 'static/dist'),
rewrites: [{ source: '**', destination: '/index.html' }],
headers: [
{
source: 'index.html',
headers: [
{
key: 'Cache-Control',
value: 'no-cache',
},
],
},
],
});
}
});
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));

View File

@ -14,10 +14,9 @@ map $http_upgrade $connection_upgrade {
server {
listen 5700;
IPV6_CONFIG
root /ql/static/dist;
ssl_session_timeout 5m;
location QL_BASE_URL/api/public/ {
location QL_BASE_URLapi/public/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -25,7 +24,7 @@ server {
proxy_buffering off;
}
location QL_BASE_URL/api/ {
location QL_BASE_URLapi/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -36,7 +35,7 @@ server {
proxy_set_header Connection $connection_upgrade;
}
location QL_BASE_URL/open/ {
location QL_BASE_URLopen/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -53,9 +52,10 @@ server {
gzip_buffers 16 8k;
gzip_http_version 1.0;
location QL_BASE_URL/ {
location QL_BASE_URL_LOCATION {
QL_ROOT_OR_ALIAS /ql/static/dist;
index index.html index.htm;
try_files $uri $uri/ QL_BASE_URL/index.html;
try_files $uri QL_BASE_URLindex.html;
}
location ~ .*\.(html)$ {

View File

@ -35,7 +35,6 @@ file_notify_js_sample=$dir_sample/notify.js
file_notify_py_sample=$dir_sample/notify.py
file_notify_py=$dir_scripts/notify.py
file_notify_js=$dir_scripts/sendNotify.js
task_error_log_path=$dir_log/task_error.log
nginx_app_conf=$dir_root/docker/front.conf
nginx_conf=$dir_root/docker/nginx.conf
dep_notify_py=$dir_dep/notify.py
@ -68,7 +67,7 @@ import_config() {
[[ -f $file_config_user ]] && . $file_config_user
[[ -f $file_env ]] && . $file_env
ql_base_url=${QlBaseUrl:-""}
ql_base_url=${QlBaseUrl:-"/"}
command_timeout_time=${CommandTimeoutTime:-""}
proxy_url=${ProxyUrl:-""}
file_extensions=${RepoFileExtensions:-"js py"}
@ -468,7 +467,15 @@ patch_version() {
init_nginx() {
cp -fv $nginx_conf /etc/nginx/nginx.conf
cp -fv $nginx_app_conf /etc/nginx/conf.d/front.conf
sed -i "s,QL_BASE_URL,${qlBaseUrl},g" /etc/nginx/conf.d/front.conf
local location_url="/"
local root_or_alias="root"
if [[ $ql_base_url != "/" ]]; then
location_url="^~${ql_base_url%*/}"
root_or_alias="alias"
fi
sed -i "s,QL_BASE_URL_LOCATION,${location_url},g" /etc/nginx/conf.d/front.conf
sed -i "s,QL_BASE_URL,${ql_base_url},g" /etc/nginx/conf.d/front.conf
sed -i "s,QL_ROOT_OR_ALIAS,${root_or_alias},g" /etc/nginx/conf.d/front.conf
ipv6=$(ip a | grep inet6)
ipv6Str=""
@ -485,11 +492,6 @@ handle_task_before() {
[[ $is_macos -eq 0 ]] && check_server
if [[ -s $task_error_log_path ]]; then
cat $task_error_log_path
echo -e "加载 config.sh 出错,请手动检查"
fi
. $file_task_before "$@"
}
@ -513,4 +515,4 @@ detect_termux
detect_macos
define_cmd
import_config $1 2>$task_error_log_path
import_config $1

View File

@ -457,12 +457,6 @@ main() {
eval echo -e "\#\# 开始执行... $begin_time\\\n" $cmd
fi
if [[ -s $task_error_log_path ]]; then
eval cat $task_error_log_path $cmd
eval echo -e "加载 config.sh 出错,请手动检查" $cmd
eval echo $cmd
fi
if [[ "$show_log" == "true" ]] && [[ $ID ]]; then
eval echo -e "请移除 -l 参数" $cmd
exit 1

16
src/app.ts Normal file
View File

@ -0,0 +1,16 @@
const baseUrl = window.__ENV__QlBaseUrl || '/';
export function modifyClientRenderOpts(memo: any) {
return {
...memo,
publicPath: baseUrl,
basename: baseUrl,
};
}
export function modifyContextOpts(memo: any) {
return {
...memo,
basename: baseUrl,
};
}

View File

@ -332,8 +332,14 @@ select:-webkit-autofill:focus {
}
.ant-pro-sider-logo {
h1 {
margin-left: 5px !important;
.title {
height: 32px;
margin: 0 5px;
font-weight: 600;
font-size: 16px;
line-height: 32px;
vertical-align: middle;
animation: pro-layout-title-hide 0.3s;
}
img {

View File

@ -280,11 +280,10 @@ export default function () {
selectedKeys={[location.pathname]}
loading={loading}
ErrorBoundary={Sentry.ErrorBoundary}
logo={<Image preview={false} src="https://qn.whyour.cn/logo.png" />}
// @ts-ignore
title={
logo={
<>
<span style={{ fontSize: 16, marginRight: 5 }}></span>
<Image preview={false} src="https://qn.whyour.cn/logo.png" />
<span className="title"></span>
<a
href={systemInfo?.changeLogLink}
target="_blank"
@ -313,6 +312,7 @@ export default function () {
</a>
</>
}
title={false}
menuItemRender={(menuItemProps: any, defaultDom: any) => {
if (
menuItemProps.isUrl ||

View File

@ -17,9 +17,9 @@ const Error = () => {
needLoading && setLoading(true);
request
.get(`${config.apiPrefix}public/health`)
.then(({ error, status }) => {
if (status === 1) {
return reloadUser();
.then(({ error, data }) => {
if (data?.status === 1) {
return;
}
if (retryTimes.current > 3) {
setData(error?.details);

View File

@ -1,6 +1,8 @@
const baseUrl = window.__ENV__QlBaseUrl || '/';
export default {
siteName: '青龙',
apiPrefix: '/api/',
apiPrefix: `${baseUrl}api/`,
authKey: 'token',
/* Layout configuration, specify which layout to use for route. */

4
typings.d.ts vendored
View File

@ -10,3 +10,7 @@ declare module '*.svg' {
}
declare module 'pstree.remy';
interface Window {
__ENV__QlBaseUrl: string;
}