diff --git a/Makefile b/Makefile
index b3c54dd957..360939321b 100644
--- a/Makefile
+++ b/Makefile
@@ -509,7 +509,7 @@ $(FOMANTIC_DEST_DIR): semantic.json web_src/fomantic/theme.config.less | node_mo
 .PHONY: webpack
 webpack: node-check $(WEBPACK_DEST)
 
-$(WEBPACK_DEST): $(WEBPACK_SOURCES) | node_modules
+$(WEBPACK_DEST): $(WEBPACK_SOURCES) webpack.config.js | node_modules
 	npx eslint web_src/js webpack.config.js
 	npx stylelint web_src/less
 	npx webpack --hide-modules --display-entrypoints=false
diff --git a/webpack.config.js b/webpack.config.js
index 14e5846ddf..57f624aa14 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -7,6 +7,7 @@ const PostCSSPresetEnv = require('postcss-preset-env');
 const PostCSSSafeParser = require('postcss-safe-parser');
 const TerserPlugin = require('terser-webpack-plugin');
 const VueLoaderPlugin = require('vue-loader/lib/plugin');
+const { statSync } = require('fs');
 const { resolve, parse } = require('path');
 const { SourceMapDevToolPlugin } = require('webpack');
 
@@ -84,6 +85,13 @@ module.exports = {
           {
             loader: 'babel-loader',
             options: {
+              cacheDirectory: true,
+              cacheCompression: false,
+              cacheIdentifier: [
+                resolve(__dirname, 'package.json'),
+                resolve(__dirname, 'package-lock.json'),
+                resolve(__dirname, 'webpack.config.js'),
+              ].map((path) => statSync(path).mtime.getTime()).join(':'),
               presets: [
                 [
                   '@babel/preset-env',