- Add html/index.html: book viewer with auto-discovering sidebar, prev/next navigation, keyboard shortcuts, and URL hash persistence - Add html/book-page.css: shared stylesheet for all book pages derived from fabula-ultima-sheet.css (dark theme, CSS variables, Cinzel/ Crimson Text fonts, common class styles) - Add book.js entry point so webpack injects the shared CSS into the book viewer; update webpack.config.js for two entry points, split CSS chunk, CopyWebpackPlugin for book pages, and /book dev server rewrite rule - Add scripts/strip_watermark.py: removes "Guest Customer (Order #52072168)" watermark artifacts from all 210 book pages - Add scripts/restyle_book.py: strips per-page <style> blocks and injects <link rel="stylesheet" href="book-page.css"> into all pages - Update Justfile deploy to scp -r dist/* for the new /book subtree Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
92 lines
2.6 KiB
JavaScript
92 lines
2.6 KiB
JavaScript
const path = require('path');
|
|
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');
|
|
|
|
module.exports = (env, argv) => {
|
|
const isProd = argv.mode === 'production';
|
|
|
|
return {
|
|
entry: {
|
|
sheet: './fabula-ultima-sheet.js',
|
|
// Imports the shared CSS so HtmlWebpackPlugin can inject it into the book page
|
|
book: './book.js',
|
|
},
|
|
output: {
|
|
filename: isProd ? '[name].[contenthash].js' : '[name].js',
|
|
path: path.resolve(__dirname, 'dist'),
|
|
clean: true,
|
|
// Disable IIFE wrapping so onclick= handlers can reach global functions
|
|
iife: false,
|
|
},
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.css$/,
|
|
use: [
|
|
isProd ? MiniCssExtractPlugin.loader : 'style-loader',
|
|
'css-loader',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
plugins: [
|
|
...(isProd
|
|
? [new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' })]
|
|
: []),
|
|
new HtmlWebpackPlugin({
|
|
template: './fabula-ultima-sheet.html',
|
|
filename: 'index.html',
|
|
chunks: ['sheet'],
|
|
scriptLoading: 'blocking',
|
|
}),
|
|
new HtmlWebpackPlugin({
|
|
template: './html/index.html',
|
|
filename: 'book/index.html',
|
|
chunks: ['book'],
|
|
scriptLoading: 'blocking',
|
|
}),
|
|
// Copy book pages to dist/book/ (excluding index.html, managed by HtmlWebpackPlugin)
|
|
new CopyWebpackPlugin({
|
|
patterns: [
|
|
{
|
|
from: 'html',
|
|
to: 'book',
|
|
globOptions: { ignore: ['**/index.html'] },
|
|
},
|
|
],
|
|
}),
|
|
],
|
|
optimization: {
|
|
minimizer: ['...', new CssMinimizerPlugin()],
|
|
splitChunks: {
|
|
cacheGroups: {
|
|
// Merge CSS from all entries into a single shared file
|
|
styles: {
|
|
name: 'styles',
|
|
type: 'css/mini-extract',
|
|
chunks: 'all',
|
|
enforce: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
devServer: {
|
|
static: [
|
|
{ directory: path.resolve(__dirname, 'dist') },
|
|
// Serve raw html/ pages at /book in dev so they don't need to be copied
|
|
{ directory: path.resolve(__dirname, 'html'), publicPath: '/book' },
|
|
],
|
|
port: 8080,
|
|
open: true,
|
|
historyApiFallback: {
|
|
rewrites: [
|
|
// /book (no trailing slash) → /book/index.html
|
|
{ from: /^\/book$/, to: '/book/index.html' },
|
|
],
|
|
},
|
|
},
|
|
};
|
|
};
|