JavaScript

Knowledge Base

JavaScript > Tools

Webpack

Installation mit

npm i -D webpack webpack-cli webpack-dev-server


webpack.config.js - Beispiel:

/* eslint-disable no-console */
const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
//const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
//const HtmlWebpackPlugin = require("html-webpack-plugin");
//const Visualizer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
 
const version = "9.5.2";
 
const config = {
    resolve: {
        // These extensions can be ommitted when importing webpack modules
        // Instead of
        // import MyComponent from "./MyComponent.jsx"
        // you can write
        // import MyComonent from "./MyComponent"
        // https://webpack.js.org/configuration/resolve/#resolveextensions
        extensions: [".js", ".json", ".jsx", ".css"],
 
        // These aliases simplify the typically relative location of files
        // Instead of
        // import MyComponent from "../../../../component/MyComponent"
        // you can write
        // import MyComponent from "component/MyComponent"
        // https://webpack.js.org/configuration/resolve/#resolvealias
        alias: {
            backend: path.resolve("src/backend"),
            components: path.resolve("src/components"),
            constants: path.resolve("src/constants"),
            entries: path.resolve("src/entries"),
            pages: path.resolve("src/pages"),
            store: path.resolve("src/store"),
            types: path.resolve("src/types"),
            utils: path.resolve("src/utils"),
        },
    },
 
    entry: {
        home: path.resolve("src/entries/home.jsx"),
        other: path.resolve("src/entries/other.jsx"),
    },
 
    module: {
        rules: [
            {
                test: /\.jsx?$/u,
                include: path.resolve("src"),
                loader: "babel-loader",
            },
        ],
    },
 
    plugins: [new CleanWebpackPlugin()],
};
 
module.exports = (env, argv) => {
    if (argv.mode === "production") {
        console.log("Webpack is running in PRODUCTION");
 
        // "production" sets process.env.NODE_ENV on DefinePlugin
        // to value production.
        // + Enables FlagDependencyUsagePlugin, FlagIncludedChunksPlugin,
        // ModuleConcatenationPlugin, NoEmitOnErrorsPlugin,
        // OccurrenceOrderPlugin, SideEffectsFlagPlugin and
        // TerserPlugin.
        config.output = {
            path: path.resolve("../QuizshowTrainingslager/JS/"),
            filename: `[name]-${version}.js`,
 
            // Name for generated chunks is based on cacheable hash only /
            // with our configuration below (single vendors bundle) this
            // affects dynamic imports only.
            chunkFilename: "[contenthash].js",
 
            // Define public path where the files are located -
            // otherwise dynamic imports are loaded from root "/" path
            publicPath: "/JS/",
        };
 
        config.optimization = {
            minimize: true, // default (PRD): true
 
            // We explicitely set splitChunks for transparency
            // although we only do minor changes to the default (PRD) settings
            // https://webpack.js.org/plugins/split-chunks-plugin/#optimizationsplitchunks
            // This configuration results in 2 initial bundles (entry + vendor) +
            // one async bundle per dynamic import:
            splitChunks: {
                //chunks: "all", // Split chunks of "initial" (standard import) and "async" (dynamic import)
                chunks: "initial", // Split chunks of sync (import) only
                minSize: 30000,
                maxSize: 0,
                minChunks: 2,
                maxAsyncRequests: 1,
                maxInitialRequests: 2, // Use max 2 initial requests (typically and entry bundle and a shared (vendor) bundle) - with dynamic imports we will have 3 in total
                automaticNameDelimiter: "-", // Use a different separator for IIS (Internet Information Services) hosted JS files
                automaticNameMaxLength: 30,
                name: true,
 
                cacheGroups: {
                    vendors: {
                        // The shared chunk will have the name "vendors-<version>.js"
                        // instead of "vendor~entry1~entry2" for all entries
                        // it's used in.
                        // CAUTION: This will fail in case there are multiple vendor chunks for different entries
                        //          (which we prevented with "maxInitialRequests:2" above) because they would
                        //                  have all the same name (but only one file remains)
                        filename: `vendors-${version}.js`,
                        test: /[\\/]node_modules[\\/]/,
                        priority: -10,
                    },
                },
            },
 
            minimizer: [
                // We explicitely set the TerserPlugin for transparency (although it is added in
                // mode "production" automatically).
                // We do only minor changes compared to the default - e. g. extracting the
                // license comments into a separate files.
                new TerserPlugin({
                    cache: true,
                    parallel: 4, // How many processes should be used during build
                    sourceMap: false, // Must be set to true if using source-maps in production
                    extractComments: true, // Extract comments in separate file
                    terserOptions: {
                        // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
                    },
                }),
            ],
 
            // If set to true it separates the webpack runtime from the entry bundle itself -
            // if complete entry bundles change seldom, this can help caching entry point
            // bundles from my point of view.
            // https://webpack.js.org/configuration/optimization/#optimizationruntimechunk
            runtimeChunk: false,
        };
 
        // This setting will set the environment for Babel into "production" mode
        // Used by babel.config.js to identify whether it's in development mode or not
        config.module.rules[0]["options"] = { envName: "production" };
 
        return config;
    }
 
    if (argv.mode === "development") {
        console.log("Webpack is running in DEVELOPMENT");
 
        // "development" sets process.env.NODE_ENV on DefinePlugin
        // to value development.
        // + Enables NamedChunksPlugin and NamedModulesPlugin.
 
        config.output = {
            filename: `[name]-${version}.js`,
            chunkFilename: "[contenthash].js",
            publicPath: "http://localhost:8080/JS/",
        };
 
        // "eval-source-map" is not optimal in case there are problems with code in IE:
        // In IE we cannot easily get the real error message and line for further
        // analysis because the code breaks at the "eval" statement line.
        config.devtool = "source-map";
 
        config.devServer = {
            publicPath: "/JS/",
            hot: true,
            https: false,
            port: 8080,
            headers: {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Headers": "*",
            },
        };
 
        // This setting will set the environment for Babel into production mode
        // Used by babel.config.js to identify whether it's in development mode or not
        config.module.rules[0]["options"] = { envName: "development" };
 
        return config;
    }
};