I'm trying to setup Rspack inside a Nx monorepo that uses React, module federation, Typescript support and css modules using scss. I got almost everything done except for the last part. The css modules just wouldn't work. The css class names get added to the rendered html in the browser (with a weird generated name using the path and all) but the css itself is missing and doesn't get rendered. Has anyone an idea how to set this up correctly? I have looked at the Rspack documentation and that helped me a lot to at least achieve to not get errors and warnings anymore when compiling.
Here is my rspack.config.js:
const {
ModuleFederationPlugin,
} = require('@module-federation/enhanced/rspack');
const mfConfig = require('./module-federation.config');
const path = require('path');
const sassConfig = {
test: /\.scss$|\.sass$/,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
// using `modern-compiler` and `sass-embedded` together significantly improve build performance,
// requires `sass-loader >= 14.2.1`
api: 'modern-compiler',
implementation: require.resolve('sass-embedded'),
},
},
],
// set to 'css/auto' if you want to support '*.module.(scss|sass)' as CSS Modules, otherwise set type to 'css'
type: 'css/auto',
};
module.exports = composePlugins(withNx(), withReact(), (config, context) => {
config.context = path.join(context.context.root, 'apps/container');
config.plugins.push(new ModuleFederationPlugin({ ...mfConfig, dts: false }));
config.output.publicPath = '/';
config.devServer = {
...config.devServer,
port: 4200,
};
// Resolve the paths in tsconfig
config.resolve = {
...config.resolve,
tsConfig: {
configFile: path.resolve(
context.context.root,
'apps/container/tsconfig.app.json',
),
references: 'auto',
},
};
// CSS setup
config.experiments = { css: true };
config.module = {
...config.module,
rules: [...config.module.rules, sassConfig],
parser: {
...config.module.parser,
'css/auto': {
namedExports: false,
},
},
};
return config;
});
Here is an example of what gets rendered in the browser:
<div class="-_src_components_Header_module_scss-ICN_appBar"></div>
I would rather like to have the class name with an hash at the end like "ICN_appBar--aslkfj" but I'm not sure how to set this up in Rspack either.
Any help would be much appreciated.
Ok, after a week of frustration, reading and trial and error, here is the solution that I have found for the issue mentioned above. It solves:
Resources that helped me on the way:
RTFM's:
And here is my rspack.config.js.
PLEASE NOTE: This works for MY project and I don't consider this a perfect solution. If you have other ideas or something to correct, feel free to let me know.
Otherwise, I hope this helps somebody.
const { composePlugins, withNx, withReact } = require('@nx/rspack');
const {
ModuleFederationPlugin,
} = require('@module-federation/enhanced/rspack');
const mfConfig = require('./module-federation.config');
const path = require('path');
const sassConfig = {
test: /\.scss$|\.sass$/,
use: [
{
loader: 'sass-loader',
options: {
// using `modern-compiler` and `sass-embedded` together significantly improve build performance,
// requires `sass-loader >= 14.2.1`
api: 'modern-compiler',
implementation: require.resolve('sass-embedded'),
},
},
],
// set to 'css/auto' if you want to support '*.module.(scss|sass)' as CSS Modules, otherwise set type to 'css'
type: 'css/auto',
exclude: '/node_modules/',
};
const cssConfig = {
test: /\.css$/,
use: [
{
loader: 'css-loader',
},
],
type: 'css/auto',
exclude: '/node_modules/',
};
module.exports = composePlugins(withNx(), withReact(), (config, context) => {
config.context = path.join(context.context.root, 'apps/container'); // Path to app
config.plugins.push(new ModuleFederationPlugin({ ...mfConfig, dts: false }));
config.output.publicPath = '/'; // '/' for host, 'auto' for remotes
config.devServer = {
...config.devServer,
port: 4200, // Make sure port fits to application
};
// Resolve the paths in tsconfig
config.resolve = {
...config.resolve,
tsConfig: {
configFile: path.resolve(
context.context.root,
'apps/container/tsconfig.app.json',
),
references: 'auto',
},
};
// CSS / SCSS setup
config.experiments = { css: true };
config.module = {
...config.module,
rules: [...config.module.rules, cssConfig, sassConfig],
parser: {
...config.module.parser,
'css/auto': {
namedExports: false,
},
},
// Make sure naming css classes of scss modules is working
generator: {
...config.module.generator,
'css/auto': {
localIdentName: '[local]-[id]',
exportsConvention: 'camel-case',
},
},
};
return config;
});