Strange Interaction Between This Plugin and MUI
DylanVause opened this issue · 7 comments
Current behaviour
When I import any component from @mui
, the build process appears to freeze. There is no output (to console or files), and when I waited quite some time for the build to progress it did not.
For example, this will build fine (takes ~3500 ms):
import { createRoot } from 'react-dom/client';
import './index.css';
const root = createRoot(document.getElementById('app')!);
root.render(
<div>
<p>Hello!</p>
<p>How are you?</p>
</div>
);
But this appears to freeze the plugin:
import { createRoot } from 'react-dom/client';
import './index.css';
import Stack from '@mui/material/Stack';
const root = createRoot(document.getElementById('app')!);
root.render(
<Stack>
<p>Hello!</p>
<p>How are you?</p>
</Stack>
);
Expected behaviour
My expectation is a successful build similar to the result when not using MUI (as described above).
Reproduction Example
I have a mini reproduction example here: https://github.com/DylanVause/mui-webpack-bug
Environment
- OS: Windows 11
- version of Node.js: v18.17.1
- version of Webpack: 5.89.0
- version of the Plugin: 3.4.0
Additional context
My Webpack config is in the reproduction repository, but I will include it here as well for convenience:
const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = [
{
name: 'client',
mode: 'development',
output: {
path: path.resolve(__dirname, 'client-dist'),
clean: true
},
resolve: {
alias: {
client: path.resolve(__dirname, 'client')
},
extensions: ['.js', '.ts']
},
module: {
rules: [
{
test: /\.tsx?$/,
include: path.resolve(__dirname, 'client'),
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
],
},
{
test: /\.css$/,
use: 'css-loader',
include: path.resolve(__dirname, 'client'),
exclude: /node_modules/,
},
{
test: /\.(ico|png|jp?g|svg)/,
type: 'asset/resource',
include: path.resolve(__dirname, 'client'),
exclude: /node_modules/,
generator: {
filename: 'img/[name].[hash:8][ext]'
}
}
],
},
plugins: [
new HtmlBundlerPlugin({
entry: 'client/',
js: {
filename: 'js/[name].[contenthash:8].js'
},
css: {
filename: 'css/[name].[contenthash:8].css'
},
})
],
optimization: {
usedExports: true,
}
},
];
By the way I absolutely love this plugin and apologize in advance if this 'bug' is just a result of me not knowing what I am doing.
Hello @DylanVause,
thanks for the issue report and the repo.
I will research this use case.
Hi @DylanVause
I can reproduce the issue and I will try to fix it.
Temporary Workaroud
Instead of importing the style file in .tsx file, define the style directly in html:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<!-- define your styles here -->
<link href="./style.css" rel="stylesheet" />
</head>
<body>
<h1>Hello World!</h1>
<div id="app"></div>
<script src="index.tsx"></script>
</body>
</html>
Remove the imported style from tsx file:
import { createRoot } from 'react-dom/client';
import Stack from '@mui/material/Stack';
//import './index.css'; // <= remove from js/tsx file
const root = createRoot(document.getElementById('app')!);
root.render(
<Stack>
<p>Hello!</p>
<p>How are you?</p>
</Stack>
);
P.S. this is realy a hard bug and will be fixed
@webdiscus Thank you for the workaround. I explored the bug some more today and learned that commenting out either import '@mui/material/Stack';
OR commenting out import './index.css';
allows for a successful build. It is only when they are BOTH included that the build fails.
I have modified my example to better illustrate this point:
import '@mui/material/Stack'; // <= disable this line or
import './index.css'; // <= disable this line to build successfully
// ^^^ If both these lines are enabled it will fail to build, regardless of the content of index.css
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('app')!);
root.render(
<div>
<p>Hello!</p>
<p>How are you?</p>
</div>
);
import '@mui/material/Stack'; // <= disable this line or import './index.css'; // <= disable this line to build successfully
yes, that's exactly what I noticed: only works with MUI or CSS.
Thank you!
I found the problem. Webpack create many circular dependencies for MUI modules, so walking through circular dependencies occurs an infinite loop. I wrote a new algorithm to find all CSS files imported in JS, that avoids circular dependencies. By me local your example already works. I must yet optimise the algorithm.
Also, I'm in process...
@DylanVause sorry for delay...
The issue is fixed in the version 3.4.4
.
Can you please check it?
Thank you! I can confirm this fix works for me as well.