const path = require("path"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const CopyPlugin = require("copy-webpack-plugin"); const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; const Handlebars = require("handlebars"); const fs = require("fs"); // Load app configuration const appConfig = JSON.parse(fs.readFileSync(path.resolve(__dirname, "config/app.json"), "utf8")); const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin"); const FRAGMENTS_PATH = "src/fragments"; // Load the fragments from the fragments directory and caches it const loadFragmentsMap = (() => { let cachedFragments = null; return async () => { if (cachedFragments === null) { cachedFragments = {}; const walkDir = async (dir, basePath = '') => { const files = fs.readdirSync(dir); await Promise.all(files.map(async file => { const filePath = path.join(dir, file); const relativePath = path.join(basePath, file); if (fs.statSync(filePath).isDirectory()) { await walkDir(filePath, relativePath); } else { const nameWithoutExt = relativePath.replace(/\.html$/, ''); const dottedPath = 'fragment-' + nameWithoutExt.replace(/\\/g, '-').replace(/\//g, '-').replace(/\./g, '-'); const content = fs.readFileSync(filePath, "utf8"); let minifiedContent; if (content.trim().startsWith(' { const fragments = await loadFragmentsMap(); console.log(`Available fragments: ${Object.keys(fragments).join(', ')}`); // Read the markdown file const markdown = require('markdown-it')({ html: true, linkify: true, typographer: true }); const markdownContent = data.toString('utf8'); const htmlContent = markdown.render(markdownContent); // Process with Handlebars for fragment insertion const template = Handlebars.compile(htmlContent); return template(fragments); }; module.exports = { entry: { distill: "./src/distill.js", main: "./src/index.js", }, output: { filename: "[name].bundle.js", path: path.resolve(__dirname, "dist"), }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"] }, { test: /\.(js|mjs)$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"], }, }, } ], }, plugins: [ new CleanWebpackPlugin(), new CopyPlugin({ patterns: [ { from: "src/fragments/*", to: "fragments/[name].html" }, { from: "src/style.css", to: "style.css" }, { from: "src/transformers-custom.css", to: "transformers-custom.css" }, { from: "content/*.png", to: "static/[name][ext]" }, { from: "content/*.svg", to: "static/[name][ext]" }, { from: "content/*.html", to: "static/[name][ext]" }, { from: "content/hf-logo.svg", to: "hf-logo.svg" }, { from: "content/article.md", to: "index.html", transform: async (content, path) => { const fragments = await loadFragmentsMap(); // Convert markdown to HTML const markdown = require('markdown-it')({ html: true, linkify: true, typographer: true }); const markdownContent = content.toString('utf8'); const htmlContent = markdown.render(markdownContent); // Extract headings for TOC generation const tocScript = ` `; // Create full HTML document with distill template const template = `
${appConfig.description}