-
Notifications
You must be signed in to change notification settings - Fork 0
/
webpack.config.js
180 lines (160 loc) · 5.1 KB
/
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* eslint-env node */
const path = require("path")
const HtmlWebPackPlugin = require("html-webpack-plugin")
const Dotenv = require("dotenv-webpack")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CopyPlugin = require("copy-webpack-plugin")
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
module.exports = (environment, props) => {
// Using "mode" CLI argument also sets process.env.NODE_ENV on DefinePlugin
// to "development" or "production"
const IS_PROD = props.mode === "production"
return {
entry: "./src/index.jsx",
output: {
publicPath: "/",
path: path.resolve(__dirname, "dist"),
// Cannot use 'contenthash' when hot reloading is enabled.
filename: IS_PROD ? "js/[name].[contenthash].js" : "js/[name].js",
},
devtool: IS_PROD ? false : "inline-source-map",
// In webpack-dev-server@3, there is a bug causing it to mis-judge the
// runtime environment when the Webpack 5 browserslist target is used.
//
// It then fallbacks to thinking a non-browser target is being used, in
// turn skipping injection of the HMR runtime, and thus breaking downstream
// integrations like this plugin.
//
// To overcome this, you can conditionally apply the browserslist only
// in production modes in your Webpack configuration:
target: IS_PROD ? "browserslist" : "web",
module: {
rules: [
{
test: /.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.css$/,
exclude: /\.module\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
},
},
"postcss-loader",
],
},
{
test: /\.css$/,
include: /\.module\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
},
},
"postcss-loader",
],
},
{
test: /\.(jpg|gif|png)$/,
use: {
loader: "url-loader",
},
},
{
test: /\.(woff(2)?|ttf|eot|svg)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "fonts/",
},
},
],
},
],
},
devServer: IS_PROD
? {}
: {
// Enable gzip compression for everything served:
compress: true,
// When using the HTML5 History API, the index.html page will likely
// have to be served in place of any 404 responses.
historyApiFallback: true,
// Full page reload/refresh when file changes are detected.
liveReload: false,
// Enables Hot Module Replacement without page refresh
hot: true,
},
plugins: [
new HtmlWebPackPlugin({
favicon: "public/doomguy.png",
template: "public/index.html",
}),
new MiniCssExtractPlugin({
// Cannot use 'contenthash' when hot reloading is enabled.
filename: IS_PROD ? "css/[name].[contenthash].css" : "css/[name].css",
}),
new Dotenv({
path: "./.env",
}),
new CopyPlugin({
patterns: [
{
from: "public/robots.txt",
to: "robots.txt",
},
],
}),
...(IS_PROD ? [] : [new ReactRefreshWebpackPlugin()]),
],
resolve: {
extensions: [".js", ".jsx"],
alias: {
// If using Lerna monorepos or symlinked libraries, react hooks will fail
// with "Hooks can only be called inside the body of a function component"
// caused by having multiple React version.
// Confirm following https://reactjs.org/warnings/invalid-hook-call-warning.html
//
// Fix this by telling Webpack to only use the main package's node_modules
// version of React related libraries.
//
// Read this for more: https://github.com/facebook/react/issues/13991
react: path.resolve("./node_modules/react"),
redux: path.resolve("./node_modules/redux"),
"react-redux": path.resolve("./node_modules/react-redux"),
"react-router-dom": path.resolve("./node_modules/react-router-dom"),
"core.ui": path.resolve("./src/core.ui/"),
"core.libs": path.resolve("./src/core.libs/"),
"layout.base": path.resolve("./src/layout.base/"),
"layout.guest": path.resolve("./src/layout.guest/"),
"layout.user": path.resolve("./src/layout.user/"),
},
},
optimization: {
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
vendor: {
test: /[/\\]node_modules[/\\]/,
name: "vendors",
chunks: "all",
},
},
},
},
}
}