Reputation: 765
I am new to NextJS
, I need to change the CSS class prefix
+ suffix
to this format:
<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>
How to change the component.module.css
CSS classes to the format of [path][name]__[local]--[hash:base64:5]
, can someone explain it to me please?
Do I need a config.js
file? I am using Next.js v10.0.9
Upvotes: 5
Views: 3154
Reputation: 50288
Next.js doesn't yet provide a built-in way to modify the css-loader
options.
However, you can still do so by customising the webpack configuration in your next.config.js
. You'll need to manually go through each css-loader
module loader and add the desired localIdentName
.
// next.config.js
module.exports = {
webpack: (config) => {
const rules = config.module.rules
.find((rule) => typeof rule.oneOf === 'object')
.oneOf.filter((rule) => Array.isArray(rule.use));
rules.forEach((rule) => {
rule.use.forEach((moduleLoader) => {
if (
moduleLoader.loader !== undefined &&
moduleLoader.loader.includes('css-loader') &&
typeof moduleLoader.options.modules === 'object'
) {
delete moduleLoader.options.modules.getLocalIdent;
moduleLoader.options = {
...moduleLoader.options,
modules: {
...moduleLoader.options.modules,
localIdentName: '[path][name]__[local]--[hash:base64:5]'
// You can also add other css-loader options here
}
};
}
});
});
return config;
}
};
Upvotes: 1
Reputation: 37
for Next.js with version >= 12
the accepted answer only works for Next.js with version < 12.
const loaderUtils = require('loader-utils')
const regexEqual = (x, y) => {
return (
x instanceof RegExp &&
y instanceof RegExp &&
x.source === y.source &&
x.global === y.global &&
x.ignoreCase === y.ignoreCase &&
x.multiline === y.multiline
)
}
/**
* Generate context-aware class names when developing locally
*/
const localIdent = (loaderContext, localIdentName, localName, options) => {
return (
loaderUtils
.interpolateName(loaderContext, btoa(unescape(encodeURIComponent(localName))), options)
// Webpack name interpolation returns `about_about.module__root` for
// `.root {}` inside a file named `about/about.module.css`. Let's simplify
// this.
.replace(/\.module_/, '_')
// Replace invalid symbols with underscores instead of escaping
// https://mathiasbynens.be/notes/css-escapes#identifiers-strings
.replace(/[^a-zA-Z0-9-_]/g, '_')
// "they cannot start with a digit, two hyphens, or a hyphen followed by a digit [sic]"
// https://www.w3.org/TR/CSS21/syndata.html#characters
.replace(/^(\d|--|-\d)/, '__$1')
)
}
function cssLoaderOptions(modules) {
const { getLocalIdent, ...others } = modules // Need to delete getLocalIdent else localIdentName doesn't work
return {
...others,
getLocalIdent: localIdent,
mode: 'local',
}
}
const path = require('path')
module.exports = {
webpack: config => {
config.resolve.modules.push(path.resolve('./'))
const oneOf = config.module.rules.find((rule) => typeof rule.oneOf === 'object')
if (oneOf) {
// Find the module which targets *.scss|*.sass files
const moduleSassRule = oneOf.oneOf.find(
(rule) => regexEqual(rule.test, /\.module\.(scss|sass)$/) //highlight-line
)
if (moduleSassRule) {
// Get the config object for css-loader plugin
const cssLoader = moduleSassRule.use.find(
({ loader }) => loader.includes('css-loader') //highlight-line
)
console.log(cssLoader,"cssloader")
if (cssLoader) {
cssLoader.options = {
...cssLoader.options,
modules: cssLoaderOptions(cssLoader.options.modules), //highlight-line
}
}
}
}
return config
},
eslint: {
// Warning: This allows production builds to successfully complete even if
// your project has ESLint errors.
ignoreDuringBuilds: true,
}
}
Upvotes: 3