import * as path from "path"; import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin"; import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin"; import HtmlWebpackPlugin from "html-webpack-plugin"; import webpack from "webpack"; import Dotenv from "dotenv-webpack"; const isDevelopment = process.env.NODE_ENV !== "production"; const config: webpack.Configuration = { mode: isDevelopment ? "development" : "production", entry: "./client/index.tsx", output: { filename: "bundle.js", path: path.resolve(__dirname, "dist/client"), }, resolve: { extensions: [".tsx", ".ts", ".js", ".mjs"], modules: [path.join(__dirname, "./client"), "node_modules"], }, module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], }, { test: /\.hbs$/, loader: "handlebars-loader", }, { test: /\.(mjs|js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { cacheDirectory: true, babelrc: false, presets: [ [ "@babel/preset-env", { targets: { browsers: "last 2 versions" }, useBuiltIns: "usage", corejs: 3, }, // or whatever your project requires ], ["@babel/preset-typescript", { onlyRemoveTypeImports: true }], "@babel/preset-react", ], plugins: [ // plugin-proposal-decorators is only needed if you're using experimental decorators in TypeScript ["@babel/plugin-proposal-decorators", { legacy: true }], ["@babel/plugin-proposal-class-properties", { loose: true }], isDevelopment && require.resolve("react-refresh/babel"), ].filter(Boolean), }, }, }, ], }, plugins: [ new Dotenv(), new ForkTsCheckerWebpackPlugin({ async: false, eslint: { files: "./client/**/*.{ts,tsx,js,jsx}", }, typescript: { configFile: "client/tsconfig.json" }, }), new HtmlWebpackPlugin({ template: "client/index.hbs", }), isDevelopment && new ReactRefreshWebpackPlugin(), ].filter(Boolean), devServer: { hot: true, contentBase: "./dist/client", overlay: true, }, devtool: isDevelopment ? "inline-source-map" : undefined, }; export default config;