/* eslint-disable @typescript-eslint/no-var-requires */ const path = require("path"); const webpack = require("webpack"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); const UnusedWebpackPlugin = require("unused-webpack-plugin"); const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); module.exports = (env, argv) => { const isDevServer = (env || {}).devServer === true; const runInContainer = (env || {}).runInContainer === true; const isDevelopment = argv.mode === "development"; const outputDirectory = isDevServer ? "dist-dev" : "dist"; const entry = "./src/index.tsx"; const statsConfig = { builtAt: true, children: false, chunks: false, chunkGroups: false, chunkModules: false, chunkOrigins: false, colors: true, entrypoints: false, }; const devServerSettings = { hot: true, port: 8000, publicPath: `/`, stats: statsConfig, }; // By default, the webpack-dev-server is not exposed outside of localhost. // When running in a container we need it accessible externally. if (runInContainer) { devServerSettings.disableHostCheck = true; devServerSettings.host = "0.0.0.0"; devServerSettings.watchOptions = { poll: true, }; } return { plugins: [ new webpack.DefinePlugin({ "process.env.NODE_ENV": isDevelopment ? '"development"' : '"production"', }), // http://stackoverflow.com/questions/29080148/expose-jquery-to-real-window-object-with-webpack new webpack.ProvidePlugin({ // Automtically detect jQuery and $ as free var in modules // and inject the jquery library // This is required by many jquery plugins jquery: "jquery", jQuery: "jquery", $: "jquery", }), new HtmlWebpackPlugin({ title: "Bitburner" + (isDevelopment ? " - development" : ""), template: "src/index.html", favicon: "favicon.ico", googleAnalytics: { trackingId: "UA-100157497-1", }, meta: {}, minify: isDevelopment ? false : { collapseBooleanAttributes: true, collapseInlineTagWhitespace: false, collapseWhitespace: false, conservativeCollapse: false, html5: true, includeAutoGeneratedTags: false, keepClosingSlash: true, minifyCSS: false, minifyJS: false, minifyURLs: false, preserveLineBreaks: false, preventAttributesEscaping: false, processConditionalComments: false, quoteCharacter: '"', removeAttributeQuotes: false, removeComments: false, removeEmptyAttributes: false, removeEmptyElements: false, removeOptionalTags: false, removeScriptTypeAttributes: false, removeStyleLinkTypeAttributes: false, removeTagWhitespace: false, sortAttributes: false, sortClassName: false, useShortDoctype: false, }, }), new MiniCssExtractPlugin({ filename: "[name].css", }), new ForkTsCheckerWebpackPlugin({ typescript: { diagnosticOptions: { semantic: true, syntactic: true, }, }, }), new UnusedWebpackPlugin({ // Source directories directories: [path.join(__dirname, "src"), path.join(__dirname, "utils")], // Exclude patterns exclude: ["*.test.js"], // Root directory (optional) root: __dirname, }), // In dev mode, use a faster method of create sourcemaps // while keeping lines/columns accurate isDevServer && new webpack.EvalSourceMapDevToolPlugin({ // Exclude vendor files from sourcemaps // This is a huge speed improvement for not much loss exclude: ["vendor"], columns: true, module: true, }), !isDevServer && new webpack.SourceMapDevToolPlugin({ filename: "[file].map", columns: true, module: true, }), isDevelopment && new ReactRefreshWebpackPlugin(), ].filter(Boolean), target: "web", entry: entry, output: { path: path.resolve(__dirname, "./"), filename: "[name].bundle.js", }, module: { rules: [ { test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { plugins: [isDevelopment && require.resolve("react-refresh/babel")].filter(Boolean), cacheDirectory: true, }, }, }, { test: /\.s?css$/, use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], }, ], }, optimization: { removeAvailableModules: true, removeEmptyChunks: true, mergeDuplicateChunks: true, flagIncludedChunks: true, occurrenceOrder: true, sideEffects: true, providedExports: true, usedExports: true, concatenateModules: false, namedModules: false, namedChunks: false, minimize: !isDevelopment, portableRecords: true, splitChunks: { cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: `${outputDirectory}/vendor`, chunks: "all", }, }, }, }, devServer: devServerSettings, resolve: { extensions: [".tsx", ".ts", ".js", ".jsx"], }, stats: statsConfig, }; };