mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-03-22 06:48:11 +00:00
dev base (kinda stable)
This commit is contained in:
12
client/entry-client-admin.jsx
Normal file
12
client/entry-client-admin.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react'
|
||||
import { hydrateRoot } from 'react-dom/client';
|
||||
import Admin from './admin.jsx';
|
||||
|
||||
import './admin/admin.less'
|
||||
|
||||
window.start_app = (props) => {
|
||||
hydrateRoot(
|
||||
document.getElementById('reactRoot'),
|
||||
<Admin {...props} />
|
||||
)
|
||||
}
|
||||
13
client/entry-client-homebrew.jsx
Normal file
13
client/entry-client-homebrew.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
import { hydrateRoot } from 'react-dom/client'
|
||||
import Homebrew from './homebrew/homebrew.jsx'
|
||||
|
||||
// CSS MUST be imported here
|
||||
import './homebrew/homebrew.less' // or wherever your CSS lives
|
||||
|
||||
window.start_app = (props) => {
|
||||
hydrateRoot(
|
||||
document.getElementById('reactRoot'),
|
||||
<Homebrew {...props} />
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import Admin from './admin.jsx';
|
||||
import Admin from './admin/admin.jsx';
|
||||
|
||||
export default (props) => renderToString(<Admin {...props} />);
|
||||
@@ -1,33 +1,66 @@
|
||||
const template = async function(name, title='', props = {}){
|
||||
import fs from "fs";
|
||||
|
||||
const isProd = process.env.NODE_ENV === "production";
|
||||
|
||||
const template = async function ({ vite, url }, name, title = "", props = {}) {
|
||||
const ogTags = [];
|
||||
const ogMeta = props.ogMeta ?? {};
|
||||
Object.entries(ogMeta).forEach(([key, value])=>{
|
||||
if(!value) return;
|
||||
const tag = `<meta property="og:${key}" content="${value}">`;
|
||||
ogTags.push(tag);
|
||||
|
||||
Object.entries(ogMeta).forEach(([key, value]) => {
|
||||
if (!value) return;
|
||||
ogTags.push(`<meta property="og:${key}" content="${value}">`);
|
||||
});
|
||||
const ogMetaTags = ogTags.join('\n');
|
||||
|
||||
const ssrModule = await import(`../build/entry-server-${name}/bundle.js`);
|
||||
const ogMetaTags = ogTags.join("\n");
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, height=device-height, interactive-widget=resizes-visual" />
|
||||
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
|
||||
<link href=${`/${name}/bundle.css`} type="text/css" rel='stylesheet' />
|
||||
<link rel="icon" href="/assets/favicon.ico" type="image/x-icon" />
|
||||
${ogMetaTags}
|
||||
<meta name="twitter:card" content="summary">
|
||||
<title>${title.length ? `${title} - The Homebrewery`: 'The Homebrewery - NaturalCrit'}</title>
|
||||
</head>
|
||||
<body>
|
||||
<main id="reactRoot">${ssrModule.default(props)}</main>
|
||||
<script src=${`/${name}/bundle.js`}></script>
|
||||
<script>start_app(${JSON.stringify(props)})</script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
// ----------------
|
||||
// PROD
|
||||
// ----------------
|
||||
if (isProd) {
|
||||
const ssrModule = await import(`../build/entry-server-${name}/bundle.js`);
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, height=device-height, interactive-widget=resizes-visual" />
|
||||
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
|
||||
<link href="/${name}/bundle.css" rel="stylesheet" />
|
||||
<link rel="icon" href="/assets/favicon.ico" type="image/x-icon" />
|
||||
${ogMetaTags}
|
||||
<meta name="twitter:card" content="summary">
|
||||
<title>${title.length ? `${title} - The Homebrewery` : "The Homebrewery - NaturalCrit"}</title>
|
||||
</head>
|
||||
<body>
|
||||
<main id="reactRoot">${ssrModule.default(props)}</main>
|
||||
<script src="/${name}/bundle.js"></script>
|
||||
<script>start_app(${JSON.stringify(props)})</script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
// ----------------
|
||||
// DEV
|
||||
// ----------------
|
||||
const { default: render } = await vite.ssrLoadModule(`/client/entry-server-${name}.jsx`);
|
||||
|
||||
let html = `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, height=device-height, interactive-widget=resizes-visual" />
|
||||
${ogMetaTags}
|
||||
<title>${title.length ? `${title} - The Homebrewery` : "The Homebrewery - NaturalCrit"}</title>
|
||||
</head>
|
||||
<body>
|
||||
<main id="reactRoot">${render(props)}</main>
|
||||
|
||||
<script type="module" src="/@vite/client"></script>
|
||||
<script type="module" src="/client/entry-client-${name}.jsx"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>`;
|
||||
|
||||
return vite.transformIndexHtml(url, html);
|
||||
};
|
||||
|
||||
export default template;
|
||||
export default template;
|
||||
|
||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -5268,9 +5268,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ci-info": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
|
||||
"integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz",
|
||||
"integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
||||
@@ -12,11 +12,13 @@
|
||||
"url": "git://github.com/naturalcrit/homebrewery.git"
|
||||
},
|
||||
"scripts": {
|
||||
"viteDev": "node scripts/dev.js",
|
||||
"viteDev1": "node scripts/dev.js",
|
||||
"viteDev2": "vite dev",
|
||||
"viteDevAdmin": "vite --config vite.config.js --ssr client/admin/admin.jsx",
|
||||
"viteBuild": "vite build",
|
||||
"viteBuild": "vite build && node scripts/compileAssets.js",
|
||||
"viteStart": "vite preview --outDir build",
|
||||
"start": "node server.js",
|
||||
"compileAssets": "node scripts/compileAssets.js --dev",
|
||||
"dev": "node --experimental-require-module scripts/dev.js",
|
||||
"quick": "node --experimental-require-module scripts/quick.js",
|
||||
"build": "node --experimental-require-module scripts/buildHomebrew.js && node --experimental-require-module scripts/buildAdmin.js",
|
||||
|
||||
90
scripts/compileAssets.js
Normal file
90
scripts/compileAssets.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import fs from "fs-extra";
|
||||
import less from "less";
|
||||
const isDev = !!process.argv.find((arg) => arg === "--dev");
|
||||
|
||||
const compileAssets = async () => {
|
||||
await fs.copy("./client/homebrew/favicon.ico", "./build/assets/favicon.ico");
|
||||
|
||||
//v==----------------------------- COMPILE THEMES --------------------------------==v//
|
||||
|
||||
// Update list of all Theme files
|
||||
const themes = { Legacy: {}, V3: {} };
|
||||
|
||||
let themeFiles = fs.readdirSync("./themes/Legacy");
|
||||
for (const dir of themeFiles) {
|
||||
const themeData = JSON.parse(fs.readFileSync(`./themes/Legacy/${dir}/settings.json`).toString());
|
||||
themeData.path = dir;
|
||||
themes.Legacy[dir] = themeData;
|
||||
//fs.copy(`./themes/Legacy/${dir}/dropdownTexture.png`, `./build/themes/Legacy/${dir}/dropdownTexture.png`);
|
||||
const src = `./themes/Legacy/${dir}/style.less`;
|
||||
((outputDirectory) => {
|
||||
less.render(
|
||||
fs.readFileSync(src).toString(),
|
||||
{
|
||||
compress: !isDev,
|
||||
},
|
||||
function (e, output) {
|
||||
fs.outputFile(outputDirectory, output.css);
|
||||
},
|
||||
);
|
||||
})(`./build/themes/Legacy/${dir}/style.css`);
|
||||
}
|
||||
|
||||
themeFiles = fs.readdirSync("./themes/V3");
|
||||
for (const dir of themeFiles) {
|
||||
const themeData = JSON.parse(fs.readFileSync(`./themes/V3/${dir}/settings.json`).toString());
|
||||
themeData.path = dir;
|
||||
themes.V3[dir] = themeData;
|
||||
fs.copy(`./themes/V3/${dir}/dropdownTexture.png`, `./build/themes/V3/${dir}/dropdownTexture.png`);
|
||||
fs.copy(`./themes/V3/${dir}/dropdownPreview.png`, `./build/themes/V3/${dir}/dropdownPreview.png`);
|
||||
const src = `./themes/V3/${dir}/style.less`;
|
||||
((outputDirectory) => {
|
||||
less.render(
|
||||
fs.readFileSync(src).toString(),
|
||||
{
|
||||
compress: !isDev,
|
||||
},
|
||||
function (e, output) {
|
||||
fs.outputFile(outputDirectory, output.css);
|
||||
},
|
||||
);
|
||||
})(`./build/themes/V3/${dir}/style.css`);
|
||||
}
|
||||
|
||||
await fs.outputFile("./themes/themes.json", JSON.stringify(themes, null, 2));
|
||||
|
||||
// await less.render(lessCode, {
|
||||
// compress : !dev,
|
||||
// sourceMap : (dev ? {
|
||||
// sourceMapFileInline: true,
|
||||
// outputSourceFiles: true
|
||||
// } : false),
|
||||
// })
|
||||
|
||||
// Move assets
|
||||
await fs.copy("./themes/fonts", "./build/fonts");
|
||||
await fs.copy("./themes/assets", "./build/assets");
|
||||
await fs.copy("./client/icons", "./build/icons");
|
||||
|
||||
//v==---------------------------MOVE CM EDITOR THEMES -----------------------------==v//
|
||||
|
||||
const editorThemesBuildDir = "./build/homebrew/cm-themes";
|
||||
await fs.copy("./node_modules/codemirror/theme", editorThemesBuildDir);
|
||||
await fs.copy("./themes/codeMirror/customThemes", editorThemesBuildDir);
|
||||
const editorThemeFiles = fs.readdirSync(editorThemesBuildDir);
|
||||
|
||||
const editorThemeFile = "./themes/codeMirror/editorThemes.json";
|
||||
if (fs.existsSync(editorThemeFile)) fs.rmSync(editorThemeFile);
|
||||
const stream = fs.createWriteStream(editorThemeFile, { flags: "a" });
|
||||
stream.write('[\n"default"');
|
||||
|
||||
for (const themeFile of editorThemeFiles) {
|
||||
stream.write(`,\n"${themeFile.slice(0, -4)}"`);
|
||||
}
|
||||
stream.write("\n]\n");
|
||||
stream.end();
|
||||
|
||||
await fs.copy("./themes/codeMirror", "./build/homebrew/codeMirror");
|
||||
};
|
||||
|
||||
compileAssets();
|
||||
57
server.js
57
server.js
@@ -1,20 +1,47 @@
|
||||
import DB from './server/db.js';
|
||||
import server from './server/app.js';
|
||||
import config from './server/config.js';
|
||||
import DB from "./server/db.js";
|
||||
import createApp from "./server/app.js";
|
||||
import config from "./server/config.js";
|
||||
import { createServer as createViteServer } from "vite";
|
||||
|
||||
DB.connect(config).then(()=>{
|
||||
// Ensure that we have successfully connected to the database
|
||||
// before launching server
|
||||
const PORT = process.env.PORT || config.get('web_port') || 8000;
|
||||
server.listen(PORT, ()=>{
|
||||
const reset = '\x1b[0m'; // Reset to default style
|
||||
const bright = '\x1b[1m'; // Bright (bold) style
|
||||
const cyan = '\x1b[36m'; // Cyan color
|
||||
const underline = '\x1b[4m'; // Underlined style
|
||||
const isProd = process.env.NODE_ENV === "production";
|
||||
|
||||
async function start() {
|
||||
let vite;
|
||||
|
||||
//==== Create Vite dev server only in development ====//
|
||||
if (!isProd) {
|
||||
vite = await createViteServer({
|
||||
server: { middlewareMode: true },
|
||||
appType: "custom",
|
||||
logLevel: 'error',
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//==== Connect to the database ====//
|
||||
await DB.connect(config).catch((err) => {
|
||||
console.error("Database connection failed:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
//==== Create the Express app ====//
|
||||
const app = await createApp(vite);
|
||||
|
||||
//==== Start listening ====//
|
||||
const PORT = process.env.PORT || config.get("web_port") || 8000;
|
||||
app.listen(PORT, () => {
|
||||
const reset = "\x1b[0m"; // Reset to default style
|
||||
const bright = "\x1b[1m"; // Bright (bold) style
|
||||
const cyan = "\x1b[36m"; // Cyan color
|
||||
const underline = "\x1b[4m"; // Underlined style
|
||||
|
||||
console.log(`\n\tserver started at: ${new Date().toLocaleString()}`);
|
||||
console.log(`\tserver on port: ${PORT}`);
|
||||
console.log(`\t${bright + cyan}Open in browser: ${reset}${underline + bright + cyan}http://localhost:${PORT}${reset}\n\n`);
|
||||
|
||||
console.log(
|
||||
`\t${bright + cyan}Open in browser: ${reset}${underline + bright + cyan}http://localhost:${PORT}${reset}\n\n`,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//==== Start the server ====//
|
||||
start();
|
||||
|
||||
1047
server/app.js
1047
server/app.js
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
server: {
|
||||
port:8000,
|
||||
fs: {
|
||||
allow: ["."],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user