Skip to content

Commit 9343cec

Browse files
committed
Splitted Webpack configuration
- Webpack configuration was splitted into three parts - common, dev and prod one, and merged with webpack-merge mergeWithRules - purging is always enabled for TailwindCSS, which speeds up development builds a lot
1 parent 44c2410 commit 9343cec

File tree

6 files changed

+132
-57
lines changed

6 files changed

+132
-57
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@
6464
"typescript": "^4.1.3",
6565
"webpack": "^5.12.2",
6666
"webpack-cli": "^4.3.1",
67-
"webpack-dev-server": "^3.11.1"
67+
"webpack-dev-server": "^3.11.1",
68+
"webpack-merge": "^5.7.3"
6869
},
6970
"prettier": {
7071
"singleQuote": true

pnpm-lock.yaml

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tailwind.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module.exports = {
2-
purge: ['src/**/*.html', 'src/**/*.tsx'],
2+
purge: {
3+
enabled: true,
4+
content: ['src/**/*.{html,tsx}'],
5+
},
36
darkMode: false, // or 'media' or 'class'
47
theme: {
58
extend: {},

webpack.config.js

Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
1-
const { DefinePlugin, HotModuleReplacementPlugin } = require('webpack');
1+
const { DefinePlugin } = require('webpack');
22
const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin');
33
const HtmlWebpackPlugin = require('html-webpack-plugin');
4-
const TerserWebackPlugin = require('terser-webpack-plugin');
5-
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
6-
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7-
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
8-
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
9-
const ESLintPlugin = require('eslint-webpack-plugin');
4+
const { CustomizeRule, mergeWithRules } = require('webpack-merge');
105
const { resolve } = require('path');
6+
const development = require('./webpack.dev');
7+
const production = require('./webpack.prod');
118

12-
module.exports = (_, { mode = 'none' }) => ({
9+
const common = (mode) => ({
1310
mode,
11+
devtool: false,
1412
output: {
1513
path: resolve(process.cwd(), 'dist'),
1614
},
17-
devtool: mode === 'development' ? 'inline-source-map' : false,
18-
devServer: {
19-
port: 3000,
20-
hot: true,
21-
},
22-
target: mode === 'development' ? 'web' : 'browserslist',
2315
resolve: {
2416
extensions: ['.ts', '.tsx', '.js', '.jsx'],
2517
plugins: [new TsconfigPathsPlugin({})],
@@ -30,9 +22,6 @@ module.exports = (_, { mode = 'none' }) => ({
3022
test: /\.css$/,
3123
exclude: /node_modules/,
3224
use: [
33-
{
34-
loader: mode === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader,
35-
},
3625
{
3726
loader: 'css-loader',
3827
options: {
@@ -43,11 +32,11 @@ module.exports = (_, { mode = 'none' }) => ({
4332
],
4433
},
4534
{
46-
test: /\.(png|jpe?g|gif|svg)$/i,
35+
test: /\.(png|jpe?g|gif|svg)$/,
4736
type: 'asset/resource',
4837
},
4938
{
50-
test: /\.tsx?$/i,
39+
test: /\.tsx?$/,
5140
exclude: /node_modules/,
5241
loader: 'babel-loader',
5342
},
@@ -60,41 +49,16 @@ module.exports = (_, { mode = 'none' }) => ({
6049
new DefinePlugin({
6150
__MODE__: JSON.stringify(mode),
6251
}),
63-
...(mode === 'development'
64-
? [new ForkTsCheckerWebpackPlugin(), new HotModuleReplacementPlugin()]
65-
: [
66-
new MiniCssExtractPlugin(),
67-
new ESLintPlugin({
68-
emitError: true,
69-
}),
70-
new CleanWebpackPlugin(),
71-
]),
7252
],
73-
optimization: {
74-
minimizer: [
75-
...(mode === 'development' ? [] : [new TerserWebackPlugin(), new CssMinimizerPlugin()]),
76-
],
77-
runtimeChunk: mode === 'development' ? undefined : 'single',
78-
splitChunks:
79-
mode === 'development'
80-
? false
81-
: {
82-
chunks: 'all',
83-
maxInitialRequests: Infinity,
84-
minSize: 0,
85-
cacheGroups: {
86-
vendor: {
87-
test: /[\\/]node_modules[\\/]/,
88-
name({ context }) {
89-
if (context) {
90-
const [, name] =
91-
/[\\/]node_modules(?:\\.pnpm)?[\\/](.*?)(?:[\\/]|$)/.exec(context) || [];
92-
return name.replace('@', '');
93-
}
94-
return null;
95-
},
96-
},
97-
},
98-
},
99-
},
10053
});
54+
55+
module.exports = (_, { mode = 'none' }) =>
56+
mergeWithRules({
57+
mode,
58+
module: {
59+
rules: {
60+
test: CustomizeRule.Match,
61+
use: CustomizeRule.Prepend,
62+
},
63+
},
64+
})(common(mode), mode === 'production' ? production : development);

webpack.dev.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const { EvalSourceMapDevToolPlugin, HotModuleReplacementPlugin } = require('webpack');
2+
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
3+
4+
module.exports = {
5+
// devtool: 'inline-source-map',
6+
devServer: {
7+
port: 3000,
8+
hot: true,
9+
},
10+
target: 'web',
11+
plugins: [
12+
new ForkTsCheckerWebpackPlugin(),
13+
new HotModuleReplacementPlugin(),
14+
new EvalSourceMapDevToolPlugin({
15+
test: /\.(m?js|ts)x?$/,
16+
}),
17+
],
18+
module: {
19+
rules: [
20+
{
21+
test: /\.css$/,
22+
exclude: /node_modules/,
23+
use: ['style-loader'],
24+
},
25+
],
26+
},
27+
};

webpack.prod.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const TerserWebackPlugin = require('terser-webpack-plugin');
2+
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3+
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
4+
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
5+
const ESLintPlugin = require('eslint-webpack-plugin');
6+
7+
module.exports = {
8+
// devtool: false,
9+
target: 'browserslist',
10+
plugins: [
11+
new CleanWebpackPlugin(),
12+
new MiniCssExtractPlugin(),
13+
new ESLintPlugin({
14+
emitError: true,
15+
}),
16+
],
17+
module: {
18+
rules: [
19+
{
20+
test: /\.css$/,
21+
use: [MiniCssExtractPlugin.loader],
22+
},
23+
],
24+
},
25+
optimization: {
26+
minimizer: [new TerserWebackPlugin(), new CssMinimizerPlugin()],
27+
runtimeChunk: 'single',
28+
splitChunks: {
29+
chunks: 'all',
30+
maxInitialRequests: Infinity,
31+
minSize: 0,
32+
cacheGroups: {
33+
vendor: {
34+
test: /[\\/]node_modules[\\/]/,
35+
name({ context }) {
36+
if (context) {
37+
const [, name] =
38+
/[\\/]node_modules(?:\\.pnpm)?[\\/](.*?)(?:[\\/]|$)/.exec(context) || [];
39+
return name.replace('@', '');
40+
}
41+
return null;
42+
},
43+
},
44+
},
45+
},
46+
},
47+
};

0 commit comments

Comments
 (0)