将 CSS 模块 kebab-case 类名转换为 Next.js 中的驼峰命名法

Jak*_*ttk 9 sass reactjs css-modules next.js

我将 CSS 模块 ( .scss) 与 Next.js 一起使用,并且有一个 kebab 命名约定。换句话说,是这样的:

.member-btn {
    background: #fff;
}
Run Code Online (Sandbox Code Playgroud)

我面临的问题是,为了使用它,className我必须像styles["member-btn"]. 例如

.member-btn {
    background: #fff;
}
Run Code Online (Sandbox Code Playgroud)

但是,我想将它与对象一起使用styles.memberBtn并像对象一样使用它(IDE​​ 也为此提供了内置支持)。例如

<Button className={styles["member-btn"]}>
    Hello world
</Button>
Run Code Online (Sandbox Code Playgroud)

这在 Next.js 中可能吗?

jul*_*ves 6

Next.js 尚未提供一种简单的内置方法来自定义 CSS 模块选项(请参阅相关 RFC vercel/next.js#15818)。这意味着您必须深入研究 webpack 并css-loader直接在您的next.config.js.

这是一个适用于最新 Next.js 版本的潜在解决方案,基于vercel/next.js#11267中的答案。

// next.config.js

module.exports = {
    // other existing configurations here...
    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'
                ) {
                    moduleLoader.options = {
                        ...moduleLoader.options,
                        modules: {
                            ...moduleLoader.options.modules,
                            // This is where we allow camelCase class names
                            exportLocalsConvention: 'camelCase'
                        }
                    };
                }
            });
        });

        return config;
    }
}
Run Code Online (Sandbox Code Playgroud)

这个想法是针对css-loaderNext.js 内部使用的目标并将exportLocalsConvention选项覆盖为'camelCase'. 这使得可以使用驼峰命名的类名,例如styles.memberBtn.


小智 5

这就是解决我的问题的方法,它将所有 css 模块类名转换为驼峰命名法

// next.config.js

module.exports = {
    webpack: (config) => {
        // camelCase style names from css modules
        config.module.rules
            .find(({oneOf}) => !!oneOf).oneOf
            .filter(({use}) => JSON.stringify(use)?.includes('css-loader'))
            .reduce((acc, {use}) => acc.concat(use), [])
            .forEach(({options}) => {
                if (options.modules) {
                    options.modules.exportLocalsConvention = 'camelCase';
                }
            });

        return config;
    },
};
Run Code Online (Sandbox Code Playgroud)