webpack.config.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. const path = require("path");
  2. const HtmlWebpackPlugin = require("html-webpack-plugin");
  3. const webpack = require("webpack");
  4. const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
  5. const dotenv = require("dotenv");
  6. const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  7. .BundleAnalyzerPlugin;
  8. const TerserPlugin = require("terser-webpack-plugin");
  9. module.exports = () => {
  10. let env = dotenv.config().parsed;
  11. if (!env) {
  12. env = process.env;
  13. }
  14. const envKeys = Object.keys(env).reduce((prev, next) => {
  15. prev[`process.env.${next}`] = JSON.stringify(env[next]);
  16. return prev;
  17. }, {});
  18. // Check first the env file and if it's empty, check out the node env of the process.
  19. let isDevelopment = env.NODE_ENV !== "production";
  20. if (process.env.NODE_ENV !== env.NODE_ENV) {
  21. isDevelopment = process.env.NODE_ENV !== "production";
  22. }
  23. /**
  24. * @type {webpack.Configuration}
  25. */
  26. const config = {
  27. entry: ["./src/index.tsx"],
  28. target: "web",
  29. mode: isDevelopment ? "development" : "production",
  30. devtool: "source-map",
  31. module: {
  32. rules: [
  33. {
  34. test: /\.(ts|tsx|mjs|js|jsx)$/,
  35. exclude: /node_modules/,
  36. use: [
  37. {
  38. loader: require.resolve("babel-loader"),
  39. options: {
  40. plugins: [
  41. isDevelopment && require.resolve("react-refresh/babel"),
  42. ].filter(Boolean),
  43. },
  44. },
  45. ],
  46. },
  47. {
  48. enforce: "pre",
  49. test: /\.js$/,
  50. loader: "source-map-loader",
  51. },
  52. {
  53. test: /\.(png|svg|jpg|gif|mp3)$/,
  54. use: ["file-loader"],
  55. },
  56. { test: /\.css$/, use: ["css-loader"] },
  57. {
  58. test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
  59. use: [
  60. {
  61. loader: "file-loader",
  62. options: {
  63. name: "[name].[ext]",
  64. outputPath: "fonts/",
  65. },
  66. },
  67. ],
  68. },
  69. ],
  70. },
  71. resolve: {
  72. modules: [path.resolve(__dirname, "src"), "node_modules"],
  73. extensions: ["*", ".tsx", ".ts", ".js", ".jsx", ".json"],
  74. },
  75. output: {
  76. filename: "bundle.js",
  77. path: path.resolve(__dirname, "build"),
  78. publicPath: "/",
  79. hashFunction: "xxhash64",
  80. },
  81. devServer: {
  82. historyApiFallback: true,
  83. disableHostCheck: true,
  84. host: "0.0.0.0",
  85. port: env.DEV_SERVER_PORT || 8080,
  86. hot: true,
  87. },
  88. plugins: [
  89. new HtmlWebpackPlugin({
  90. template: path.resolve(__dirname, "src", "index.html"),
  91. segmentKey: `${process.env.SEGMENT_PUBLIC_KEY}`,
  92. }),
  93. new webpack.DefinePlugin(envKeys),
  94. isDevelopment && new ReactRefreshWebpackPlugin(),
  95. ].filter(Boolean),
  96. };
  97. if (!isDevelopment) {
  98. config.optimization = {
  99. minimize: true,
  100. minimizer: [
  101. new TerserPlugin({
  102. test: /\.(ts|tsx|mjs|js|jsx)$/,
  103. terserOptions: {
  104. parse: {
  105. // We want terser to parse ecma 8 code. However, we don't want it
  106. // to apply minification steps that turns valid ecma 5 code
  107. // into invalid ecma 5 code. This is why the `compress` and `output`
  108. ecma: 8,
  109. },
  110. compress: {
  111. ecma: 5,
  112. warnings: false,
  113. inline: 2,
  114. },
  115. mangle: {
  116. // Find work around for Safari 10+
  117. safari10: true,
  118. },
  119. output: {
  120. ecma: 5,
  121. comments: false,
  122. ascii_only: true,
  123. },
  124. },
  125. // Use multi-process parallel running to improve the build speed
  126. parallel: true,
  127. }),
  128. ],
  129. };
  130. }
  131. if (env.ENABLE_ANALYZER) {
  132. config.plugins.push(new BundleAnalyzerPlugin());
  133. }
  134. if (env.ENABLE_PROXY) {
  135. if (!env.API_SERVER) {
  136. throw new Error(
  137. "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"
  138. );
  139. }
  140. config.devServer.proxy = {
  141. "/api": {
  142. logLevel: "debug",
  143. target: env.API_SERVER, // target host
  144. changeOrigin: true, // needed for virtual hosted sites
  145. ws: true, // proxy websockets
  146. },
  147. };
  148. }
  149. return config;
  150. };