mirror of
https://github.com/imputnet/cobalt.git
synced 2025-06-28 09:28:29 +00:00
ESBuild integration
This commit is contained in:
parent
99cf7a238c
commit
7d3d1ca229
@ -24,10 +24,12 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
|
"esbuild": "^0.14.49",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-rate-limit": "^6.3.0",
|
"express-rate-limit": "^6.3.0",
|
||||||
"ffmpeg-static": "^5.0.0",
|
"ffmpeg-static": "^5.0.0",
|
||||||
"got": "^12.1.0",
|
"got": "^12.1.0",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
"node-cache": "^5.1.2",
|
"node-cache": "^5.1.2",
|
||||||
"url-pattern": "^1.0.3",
|
"url-pattern": "^1.0.3",
|
||||||
"xml-js": "^1.6.11",
|
"xml-js": "^1.6.11",
|
||||||
|
@ -13,6 +13,10 @@ import { apiJSON } from "./modules/sub/utils.js";
|
|||||||
import loc from "./modules/sub/i18n.js";
|
import loc from "./modules/sub/i18n.js";
|
||||||
import { Bright, Cyan } from "./modules/sub/consoleText.js";
|
import { Bright, Cyan } from "./modules/sub/consoleText.js";
|
||||||
import stream from "./modules/stream/stream.js";
|
import stream from "./modules/stream/stream.js";
|
||||||
|
import { UUID } from "./modules/sub/crypto.js";
|
||||||
|
import { buildJS, buildCSS } from "./modules/builder.js";
|
||||||
|
import { lookup } from "mime-types";
|
||||||
|
import { Readable } from "stream";
|
||||||
|
|
||||||
const commitHash = shortCommit();
|
const commitHash = shortCommit();
|
||||||
const app = express();
|
const app = express();
|
||||||
@ -109,18 +113,69 @@ if (fs.existsSync('./.env')) {
|
|||||||
"hash": commitHash,
|
"hash": commitHash,
|
||||||
"type": "default",
|
"type": "default",
|
||||||
"lang": req.header('Accept-Language') ? req.header('Accept-Language').slice(0, 2) : "en",
|
"lang": req.header('Accept-Language') ? req.header('Accept-Language').slice(0, 2) : "en",
|
||||||
"useragent": req.header('user-agent') ? req.header('user-agent') : genericUserAgent
|
"useragent": req.header('user-agent') ? req.header('user-agent') : genericUserAgent,
|
||||||
|
"distUUID": req.app.get('currentDistUUID'),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.get("/favicon.ico", async (req, res) => {
|
app.get("/favicon.ico", async (req, res) => {
|
||||||
res.redirect('/icons/favicon.ico');
|
res.redirect('/icons/favicon.ico');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.head("/dist/:uuid/:file", (req, res) => {
|
||||||
|
let { uuid, file } = req.params,
|
||||||
|
dist = req.app.get(`dist~${uuid}`);
|
||||||
|
|
||||||
|
if (!dist || !dist.files.hasOwnProperty(file)) {
|
||||||
|
res.sendStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader('Content-Type', lookup(file));
|
||||||
|
res.setHeader('Content-Length', dist.files[file].length);
|
||||||
|
|
||||||
|
res.status(204);
|
||||||
|
res.end();
|
||||||
|
res.sendStatus(500);
|
||||||
|
});
|
||||||
|
app.get("/dist/:uuid/:file", (req, res) => {
|
||||||
|
let { uuid, file } = req.params,
|
||||||
|
dist = req.app.get(`dist~${uuid}`);
|
||||||
|
|
||||||
|
if (!dist || !dist.files.hasOwnProperty(file)) {
|
||||||
|
res.sendStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader('Content-Type', lookup(file));
|
||||||
|
|
||||||
|
const readableStream = Readable.from(dist.files[file]);
|
||||||
|
readableStream.pipe(res);
|
||||||
|
});
|
||||||
|
|
||||||
app.get("/*", async (req, res) => {
|
app.get("/*", async (req, res) => {
|
||||||
res.redirect('/')
|
res.redirect('/')
|
||||||
});
|
});
|
||||||
app.listen(process.env.port, () => {
|
app.listen(process.env.port, () => {
|
||||||
console.log(`\n${Bright(`${appName} (${version})`)}\n\nURL: ${Cyan(`${process.env.selfURL}`)}\nPort: ${process.env.port}\nCurrent commit: ${Bright(`${commitHash}`)}\nStart time: ${Bright(Math.floor(new Date().getTime()))}\n`)
|
console.log(`\n${Bright(`${appName} (${version})`)}\n\nURL: ${Cyan(`${process.env.selfURL}`)}\nPort: ${process.env.port}\nCurrent commit: ${Bright(`${commitHash}`)}\nStart time: ${Bright(Math.floor(new Date().getTime()))}\n`)
|
||||||
|
|
||||||
|
// Building JS and CSS with builder module
|
||||||
|
Promise.all([
|
||||||
|
buildJS(),
|
||||||
|
buildCSS()
|
||||||
|
]).then(([js, css]) => {
|
||||||
|
let currentDistUUID = UUID(),
|
||||||
|
// TODO: Move deep copy to utils
|
||||||
|
currentDist = {
|
||||||
|
uuid: currentDistUUID,
|
||||||
|
files: JSON.parse(JSON.stringify(css.fontData))
|
||||||
|
};
|
||||||
|
|
||||||
|
currentDist.files[`bundle.${commitHash}.js`] = js;
|
||||||
|
currentDist.files[`bundle.${commitHash}.css`] = css.code;
|
||||||
|
|
||||||
|
// e is real 2401
|
||||||
|
app.set('currentDistUUID', currentDistUUID);
|
||||||
|
app.set(`dist~${currentDistUUID}`, currentDist);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('Required config files are missing. Please run "npm run setup" first.')
|
console.log('Required config files are missing. Please run "npm run setup" first.')
|
||||||
|
29
src/modules/builder.js
Normal file
29
src/modules/builder.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { readFile, readdir } from "fs/promises";
|
||||||
|
|
||||||
|
import * as esbuild from "esbuild";
|
||||||
|
|
||||||
|
export async function buildJS () {
|
||||||
|
let originalJS = await readFile('./src/static/cobalt.js', { encoding: 'utf-8' }),
|
||||||
|
transformedJS = await esbuild.transform(originalJS, { minify: true });
|
||||||
|
|
||||||
|
return transformedJS.code
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Make it work with new fonts
|
||||||
|
export async function buildCSS () {
|
||||||
|
let mainCSS = await readFile('./src/static/cobalt.css', { encoding: 'utf-8' }),
|
||||||
|
fontCSS = await readFile('./src/static/fonts/notosansmono/notosansmono.css', { encoding: 'utf-8' }),
|
||||||
|
fontFiles = (await readdir('./src/static/fonts/notosansmono/')).filter((f) => f.endsWith('.woff2')),
|
||||||
|
transformedCSS = await esbuild.transform(fontCSS + mainCSS, { minify: true, loader: 'css' });
|
||||||
|
|
||||||
|
const fontData = {}
|
||||||
|
for (let index in fontFiles) {
|
||||||
|
const filename = fontFiles[index]
|
||||||
|
fontData[filename] = await readFile(`./src/static/fonts/notosansmono/${filename}`, { encoding: 'utf-8' })
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: transformedCSS.code,
|
||||||
|
fontData: fontData
|
||||||
|
}
|
||||||
|
}
|
@ -47,8 +47,7 @@ export default function(obj) {
|
|||||||
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png" />
|
||||||
|
|
||||||
<link rel="manifest" href="cobalt.webmanifest" />
|
<link rel="manifest" href="cobalt.webmanifest" />
|
||||||
<link rel="stylesheet" href="cobalt.css" />
|
<link rel="stylesheet" href="dist/${obj.distUUID}/bundle.${obj.hash}.css" />
|
||||||
<link rel="stylesheet" href="fonts/notosansmono/notosansmono.css" />
|
|
||||||
|
|
||||||
<noscript><div style="margin: 2rem;">${loc(obj.lang, 'strings', 'noScript')}</div></noscript>
|
<noscript><div style="margin: 2rem;">${loc(obj.lang, 'strings', 'noScript')}</div></noscript>
|
||||||
</head>
|
</head>
|
||||||
@ -194,7 +193,7 @@ export default function(obj) {
|
|||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript">const loc = {noInternet:"${loc(obj.lang, 'apiError', 'noInternet')}"}</script>
|
<script type="text/javascript">const loc = {noInternet:"${loc(obj.lang, 'apiError', 'noInternet')}"}</script>
|
||||||
<script type="text/javascript" src="cobalt.js"></script>
|
<script type="text/javascript" src="dist/${obj.distUUID}/bundle.${obj.hash}.js"></script>
|
||||||
</html>`;
|
</html>`;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return `${loc('en', 'apiError', 'noRender', obj.hash)}`;
|
return `${loc('en', 'apiError', 'noRender', obj.hash)}`;
|
||||||
|
Loading…
Reference in New Issue
Block a user