const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); const dotenv = require("dotenv"); const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") .BundleAnalyzerPlugin; const TerserPlugin = require("terser-webpack-plugin"); module.exports = () => { const env = dotenv.config().parsed; const envKeys = Object.keys(env).reduce((prev, next) => { prev[`process.env.${next}`] = JSON.stringify(env[next]); return prev; }, {}); // Check first the env file and if it's empty, check out the node env of the process. let isDevelopment = env.NODE_ENV !== "production"; if (process.env.NODE_ENV !== env.NODE_ENV) { isDevelopment = process.env.NODE_ENV !== "production"; } /** * @type {webpack.Configuration} */ const config = { entry: ["./src/index.tsx"], target: "web", mode: isDevelopment ? "development" : "production", module: { rules: [ { test: /\.(ts|tsx|mjs|js|jsx)$/, exclude: /node_modules/, use: [ { loader: require.resolve("babel-loader"), options: { plugins: [ isDevelopment && require.resolve("react-refresh/babel"), ].filter(Boolean), }, }, ], }, { enforce: "pre", test: /\.js$/, loader: "source-map-loader", }, { test: /\.(png|svg|jpg|gif|mp3)$/, use: ["file-loader"], }, { test: /\.css$/, use: ["css-loader"] }, { test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/, use: [ { loader: "file-loader", options: { name: "[name].[ext]", outputPath: "fonts/", }, }, ], }, ], }, resolve: { modules: [path.resolve(__dirname, "src"), "node_modules"], extensions: ["*", ".tsx", ".ts", ".js", ".jsx", ".json"], }, output: { filename: "bundle.js", path: path.resolve(__dirname, "build"), publicPath: "/", }, devServer: { historyApiFallback: true, disableHostCheck: true, host: "0.0.0.0", port: env.DEV_SERVER_PORT || 8080, hot: true, }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, "src", "index.html"), segmentKey: `${process.env.SEGMENT_PUBLIC_KEY}`, }), new webpack.DefinePlugin(envKeys), isDevelopment && new ReactRefreshWebpackPlugin(), ].filter(Boolean), }; if (!isDevelopment) { config.optimization = { minimize: true, minimizer: [ new TerserPlugin({ test: /\.(ts|tsx|mjs|js|jsx)$/, terserOptions: { parse: { // We want terser to parse ecma 8 code. However, we don't want it // to apply minification steps that turns valid ecma 5 code // into invalid ecma 5 code. This is why the `compress` and `output` ecma: 8, }, compress: { ecma: 5, warnings: false, inline: 2, }, mangle: { // Find work around for Safari 10+ safari10: true, }, output: { ecma: 5, comments: false, ascii_only: true, }, }, // Use multi-process parallel running to improve the build speed parallel: true, }), ], }; } if (env.ENABLE_ANALYZER) { config.plugins.push(new BundleAnalyzerPlugin()); } console.log(env); if (env.ENABLE_PROXY) { console.log("WORKED!"); if (!env.API_SERVER) { throw new Error( "API_SERVER is not present on .env! Please setup the api server url if you want the proxy to work! API_SERVER example: http://localhost:8080" ); } config.devServer.proxy = { "/api": { logLevel: "debug", target: env.API_SERVER, // target host changeOrigin: true, // needed for virtual hosted sites ws: true, // proxy websockets }, }; } return config; };