1
votes

Hy,

I'm new to webpack and after hard learning I know that I know nothing :-).

I'm using React and I have 2 questions:

  1. How can I run my build version in the browser, for the lighthouse test. At the moment I'm using npm run dist (below package.json). Which is working but I have the feeling it is not the correct way and my dist folder gets deleted. If I use npx create-react-app I can use serve -s build therefor.
  2. If I make my Lighthouse performance test I get "Enable text compression". So I installed the compression-webpack-plugin and brotli-webpack-plugin. I have now in the dist folder the br and gz files but in the HTTP response header I don't get Content-Encoding: br or gzip and lighthouse still blames me for this.

package.jsong

"scripts": {
        "start": "webpack-dev-server --config webpack.dev.js --open --progress --colors --hot",
        "dist": "webpack-dev-server --config webpack.prod.js --open  --mode production",
        "build": "webpack --config webpack.prod.js"
}

webpack.common.js

const HtmlWebPackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
    entry: {
        main: "./src/index.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            },
            {
                test: /\.html$/,
                use: [
                    {
                        loader: "html-loader",
                        options: {
                            attributes: true
                        }
                    }
                ]
            },
            {
                test: /\.(svg|png|jpg|gif|webp|jpeg)$/,
                use: {
                    loader: "file-loader",
                    options: {
                        name: "[name].[hash].[ext]",
                        outputPath: "imgs"
                    }
                }
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebPackPlugin({
            template: "./src/index.html",
            filename: "./index.html"
        })
    ]
};

webpack.dev.js

var path = require("path");
const { merge } = require("webpack-merge");
const common = require("./webpack.common");

module.exports = merge(common, {
    mode: "development",
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].bundle.js",
        publicPath: "/"
    },
    devServer: {
        historyApiFallback: true,
        contentBase: "./dist"
    }
});

webpack.prod.js

var path = require("path");
const { merge } = require("webpack-merge");
const common = require("./webpack.common");
const CompressionPlugin = require("compression-webpack-plugin");
const BrotliPlugin = require("brotli-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");

module.exports = merge(common, {
    mode: "production",
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].[hash].bundle.js"
    },
    devtool: "source-map",
    performance: {
        hints: false
    },
    optimization: {
        splitChunks: {
            chunks: "all"
        },
        minimizer: [
            new TerserPlugin({
                parallel: true,
                cache: true,
                sourceMap: true
            })
        ]
    },
    plugins: [
        new CompressionPlugin({
            filename: "[path].gz[query]",
            algorithm: "gzip",
            test: /\.(js|html|svg)$/,
            threshold: 8192,
            minRatio: 0.8
        }),
        new BrotliPlugin({
            asset: "[path].br[query]",
            test: /\.(js|html|svg)$/,
            threshold: 10240,
            minRatio: 0.8
        })
    ]
});

.babelrc

{
    "presets": ["@babel/preset-env", "@babel/preset-react"],
    "plugins": [["@babel/transform-runtime"]]
}

THX for any help.

2

2 Answers

1
votes

If you run the build script you will get the optimized code that you can deploy on a webserver. Running npx serve build would be an easy way to simulate a webserver with the bulid files. I guess the dist script does the same using the webpack dev server.

Text compression is something you would normally configure on the webserver or proxy that hosts your website. I guess these webpack plugins do the same thing but it's normally a one liner in a webserver or proxy and you don't have to interfere with the create-react-app standard config.

Text compression examples:

0
votes

Here the solution:

I added server.js

const express = require("express");
const path = require("path");
const port = 8080;
const app = express();

app.get("*.js", (req, res, next) => {
    req.url = req.url + ".br";
    res.set("Content-Encoding", "br");
    res.set("Content-Type", "application/javascript; charset=UTF-8");
    next();
});

app.use(express.static("./dist"));

app.get("*", (req, res) => {
    res.sendFile(path.resolve("./dist", "index.html"));
});

app.listen(port);
console.log("Server started");

Also changed my package.json

  "scripts": {
        "stard": "webpack-dev-server --config webpack.dev.js --open --progress --colors --hot",
        "build": "webpack --config webpack.prod.js",
        "prod": "node server.js"
},

had to add to my webpack.prod.js publicPath: "/"

...
output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].[hash].bundle.js",
        publicPath: "/"
},
...