Build typescript website into single html file

  Kiến thức lập trình

I have a html page, including some css and typescript which I use to prettify some logs.
While so far my build consisted of running the typescript compiler and telling it to watch for changes (tsc -w), I would like to bundle all the files (css, html, javascript generated from typescript) into a single file, so that the prettified logs are fully selfcontained in a single file and can be exchanged easily.

I have looked into webpack, but stuggle with telling webpack to transform the template, so that the compiled typescript, and referenced css files are inlined. I am not tied to webpack, inc ase anyone knows a better tool for the job.

MWE:

This should be enough of a MWE skeleton to get the issues across. I would like <link rel="stylesheet" href="..."> and <script src="..."> to be inlined (also to run tsc on the typescript files which generate the js)

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>LogView</title>
    <link rel="stylesheet" href="logview.css">
    <link rel="stylesheet" href="eyesymbols.css">
    <link rel="stylesheet" href="DropDownButtonSymbolFonts.css"> <!-- apparently adding a font into a shadowdom does not work, so add it to head -->
</head>

<body>
    <div id="logview"></div>
    <div id="controls"></div>
    <script src="logview.js" async defer></script> <!-- Actual logic, logview.ts -->
    <script src="DropDownButton.js" async defer></script> <!-- Customelement, backed by DropDownButton.ts -->
</body>

</html>

Webpack config:

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HTMLInlineCSSWebpackPlugin = require("html-inline-css-webpack-plugin").default;

module.exports = {
    mode: "development", // TODO: how should we switch this between development and production?
    devtool: false, // TODO: what is the correct setting here, to either do no transform or fast builds?
    entry: {
        dropdown: "./src/DropDownButton.ts",
        logview: "./src/logview.ts",
        //index: "./src/logview.html",
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css",
        }),
        new HtmlWebpackPlugin({
            filename: "logview.html",
            template: "./src/logview.html",
            chunks: [],
            inlineSource: ".(js|css)$",
        }),
        new HTMLInlineCSSWebpackPlugin(),//{filter: () => { return true; }}),
    ],
    module: {
        rules: [
            {
                test: /.tsx?$/,
                use: "ts-loader",
                exclude: /node_modules/,
            },
            {
                test: /.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    //"style-loader",
                    "css-loader",
                ],
                type: "asset/inline",
            }
        ],
    },
    resolve: {
        extensions: [ ".tsx", ".ts", ".js" ],
    },
    output: {
        filename: "[name].js",
        path: path.resolve(__dirname, "dist"),
        clean: true,
    },
};

LEAVE A COMMENT