mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-03 19:30:51 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2be7ced21a | ||
|
|
b61155d215 | ||
|
|
5488d6153d | ||
|
|
30f5300bb4 | ||
|
|
52169200f1 | ||
|
|
80b2597611 |
@@ -9,8 +9,10 @@ https://github.com/router-for-me/CLIProxyAPI
|
||||
Example URL:
|
||||
https://remote.router-for.me/
|
||||
|
||||
Minimum required version: ≥ 5.0.0
|
||||
Recommended version: ≥ 5.2.6
|
||||
Minimum required version: ≥ 6.0.0
|
||||
Recommended version: ≥ 6.0.19
|
||||
|
||||
Starting from version 6.0.19, the WebUI has been integrated into the main program and is accessible via `/management.html`.
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ https://remote.router-for.me/
|
||||
|
||||
最低可用版本 ≥ 5.0.0
|
||||
推荐版本 ≥ 5.2.6
|
||||
自6.0.19起WebUI已经集成在主程序中 可以通过/management.html访问
|
||||
|
||||
## 功能特点
|
||||
|
||||
|
||||
132
build.js
Normal file
132
build.js
Normal file
@@ -0,0 +1,132 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const projectRoot = __dirname;
|
||||
const distDir = path.join(projectRoot, 'dist');
|
||||
|
||||
const sourceFiles = {
|
||||
html: path.join(projectRoot, 'index.html'),
|
||||
css: path.join(projectRoot, 'styles.css'),
|
||||
i18n: path.join(projectRoot, 'i18n.js'),
|
||||
app: path.join(projectRoot, 'app.js')
|
||||
};
|
||||
|
||||
const logoCandidates = ['logo.png', 'logo.jpg', 'logo.jpeg', 'logo.svg', 'logo.webp', 'logo.gif'];
|
||||
const logoMimeMap = {
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.webp': 'image/webp',
|
||||
'.gif': 'image/gif'
|
||||
};
|
||||
|
||||
function readFile(filePath) {
|
||||
try {
|
||||
return fs.readFileSync(filePath, 'utf8');
|
||||
} catch (err) {
|
||||
console.error(`读取文件失败: ${filePath}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function readBinary(filePath) {
|
||||
try {
|
||||
return fs.readFileSync(filePath);
|
||||
} catch (err) {
|
||||
console.error(`读取文件失败: ${filePath}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function escapeForScript(content) {
|
||||
return content.replace(/<\/(script)/gi, '<\\/$1');
|
||||
}
|
||||
|
||||
function escapeForStyle(content) {
|
||||
return content.replace(/<\/(style)/gi, '<\\/$1');
|
||||
}
|
||||
|
||||
function ensureDistDir() {
|
||||
if (fs.existsSync(distDir)) {
|
||||
fs.rmSync(distDir, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(distDir);
|
||||
}
|
||||
|
||||
function loadLogoDataUrl() {
|
||||
for (const candidate of logoCandidates) {
|
||||
const filePath = path.join(projectRoot, candidate);
|
||||
if (!fs.existsSync(filePath)) continue;
|
||||
|
||||
const ext = path.extname(candidate).toLowerCase();
|
||||
const mime = logoMimeMap[ext];
|
||||
if (!mime) {
|
||||
console.warn(`未知 Logo 文件类型,跳过内联: ${candidate}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const buffer = readBinary(filePath);
|
||||
const base64 = buffer.toString('base64');
|
||||
return `data:${mime};base64,${base64}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function build() {
|
||||
ensureDistDir();
|
||||
|
||||
let html = readFile(sourceFiles.html);
|
||||
const css = escapeForStyle(readFile(sourceFiles.css));
|
||||
const i18n = escapeForScript(readFile(sourceFiles.i18n));
|
||||
const app = escapeForScript(readFile(sourceFiles.app));
|
||||
|
||||
html = html.replace(
|
||||
'<link rel="stylesheet" href="styles.css">',
|
||||
`<style>
|
||||
${css}
|
||||
</style>`
|
||||
);
|
||||
|
||||
html = html.replace(
|
||||
'<script src="i18n.js"></script>',
|
||||
`<script>
|
||||
${i18n}
|
||||
</script>`
|
||||
);
|
||||
|
||||
html = html.replace(
|
||||
'<script src="app.js"></script>',
|
||||
`<script>
|
||||
${app}
|
||||
</script>`
|
||||
);
|
||||
|
||||
const logoDataUrl = loadLogoDataUrl();
|
||||
if (logoDataUrl) {
|
||||
const logoScript = `<script>window.__INLINE_LOGO__ = "${logoDataUrl}";</script>`;
|
||||
if (html.includes('</body>')) {
|
||||
html = html.replace('</body>', `${logoScript}\n</body>`);
|
||||
} else {
|
||||
html += `\n${logoScript}`;
|
||||
}
|
||||
} else {
|
||||
console.warn('未找到可内联的 Logo 文件,将保持运行时加载。');
|
||||
}
|
||||
|
||||
const outputPath = path.join(distDir, 'index.html');
|
||||
fs.writeFileSync(outputPath, html, 'utf8');
|
||||
|
||||
console.log('构建完成: dist/index.html');
|
||||
}
|
||||
|
||||
try {
|
||||
build();
|
||||
} catch (error) {
|
||||
console.error('构建失败:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
1195
index.html
1195
index.html
File diff suppressed because it is too large
Load Diff
2074
package-lock.json
generated
2074
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -6,9 +6,7 @@
|
||||
"scripts": {
|
||||
"start": "npx serve .",
|
||||
"dev": "npx serve . --port 3000",
|
||||
"prebuild": "node build-scripts/prepare-html.js",
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"postbuild": "rm -f index.build.html",
|
||||
"build": "node build.js",
|
||||
"lint": "echo '使用浏览器开发者工具检查代码'"
|
||||
},
|
||||
"keywords": [
|
||||
@@ -20,14 +18,7 @@
|
||||
"author": "CLI Proxy API WebUI",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"css-loader": "^6.8.1",
|
||||
"html-inline-script-webpack-plugin": "^3.2.1",
|
||||
"html-loader": "^4.2.0",
|
||||
"html-webpack-plugin": "^5.5.4",
|
||||
"serve": "^14.2.1",
|
||||
"style-loader": "^3.3.3",
|
||||
"webpack": "^5.102.0",
|
||||
"webpack-cli": "^5.1.4"
|
||||
"serve": "^14.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -35,5 +26,6 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "local"
|
||||
}
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
1194
styles.css
1194
styles.css
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user