Files
fabula-ultima-html/webpack.config.js
Drew Malzahn fcbd0acfb2 refactor: Move source files from root into src/
Relocates book.js, fabula-ultima-sheet.css, and fabula-ultima-sheet.html
into src/ to consolidate all source files under one directory. Updates
webpack entry points, HTML template path, and CSS import accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 04:14:30 +00:00

156 lines
4.3 KiB
JavaScript

const path = require("path");
const fs = require("fs");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
function readPages(dir) {
const pageNums = fs
.readdirSync(dir)
.map(f => { const m = f.match(/^(\d+)\.html$/); return m ? parseInt(m[1], 10) : null; })
.filter(n => n !== null)
.sort((a, b) => a - b);
return pageNums.map(n => {
let content = fs.readFileSync(path.join(dir, `${n}.html`), "utf8");
content = content.replace(/[ \t]*<link[^>]+>\n?/g, "").trim();
return { n, content };
});
}
function bookTemplate(title, logoText, dir) {
const pages = readPages(dir);
const data = JSON.stringify({ title, logoText, pages });
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>${title}</title>
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;600;700&family=Crimson+Text:ital,wght@0,400;0,600;1,400&family=Inconsolata:wght@400;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/css/book-page.css" />
<link rel="stylesheet" href="/css/book-layout.css" />
</head>
<body>
<script>window.__BOOK_DATA__ = ${data};</script>
<div id="root"></div>
</body>
</html>`;
}
module.exports = (env, argv) => {
const isProd = argv.mode === "production";
return {
entry: {
sheet: "./src/sheet-main.jsx",
book: "./src/book.js",
},
output: {
filename: isProd ? "[name].[contenthash].js" : "[name].js",
path: path.resolve(__dirname, "dist"),
clean: true,
iife: false,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: { presets: ["@babel/preset-react"] },
},
},
{
test: /\.css$/,
use: [
isProd ? MiniCssExtractPlugin.loader : "style-loader",
"css-loader",
],
},
],
},
resolve: {
extensions: [".js", ".jsx"],
},
plugins: [
...(isProd
? [new MiniCssExtractPlugin({ filename: "[name].[contenthash].css" })]
: []),
new HtmlWebpackPlugin({
template: "./src/fabula-ultima-sheet.html",
filename: "index.html",
chunks: ["sheet"],
scriptLoading: "blocking",
}),
new HtmlWebpackPlugin({
templateContent: bookTemplate(
"Fabula Ultima - Core Rulebook",
"Core Rules",
"./books/core"
),
filename: "books/core/index.html",
chunks: ["book"],
scriptLoading: "blocking",
}),
new HtmlWebpackPlugin({
templateContent: bookTemplate(
"Fabula Ultima - Natural Fantasy Atlas",
"Natural Fantasy Atlas",
"./books/natural-fantasy-atlas"
),
filename: "books/natural-fantasy-atlas/index.html",
chunks: ["book"],
scriptLoading: "blocking",
}),
new CopyWebpackPlugin({
patterns: [
{
from: "books",
to: "books",
globOptions: { ignore: ["**/index.html"] },
},
],
}),
new CopyWebpackPlugin({
patterns: [
{
from: "css",
to: "css",
globOptions: { ignore: ["**/index.html"] },
},
],
}),
],
optimization: {
minimizer: ["...", new CssMinimizerPlugin()],
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},
devServer: {
static: [
{ directory: path.resolve(__dirname, "dist") },
{ directory: path.resolve(__dirname, "books"), publicPath: "/books" },
{ directory: path.resolve(__dirname, "css"), publicPath: "/css" },
],
port: 8080,
open: true,
historyApiFallback: {
rewrites: [
{ from: /^\/book$/, to: "/book/index.html" },
],
},
},
};
};