使用postcss-modules插件来动态生成类名。在webpack配置文件中安装postcss-modules插件,并使用它来处理CSS文件。这将生成一个映射,将原始类名替换为唯一的类名。然后,在JSX文件中,使用生成的类名来代替原始的styleName。这样,在编译时,babel-plugin-react-css-modules将生成的类名转换为className,并将其应用于DOM元素。
以下是一个示例webpack配置文件:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const postcssModules = require('postcss-modules');
const PATHS = {
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'build'),
};
module.exports = {
entry: {
app: PATHS.app,
},
output: {
path: PATHS.build,
filename: '[name].js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
template: path.join(PATHS.app, 'index.html'),
}),
new ExtractTextPlugin('[name].css'),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react'],
plugins: [
['react-css-modules', {
generateScopedName: '[name]__[local]___[hash:base64:5]',
filetypes: {
'.scss': {
syntax: 'postcss-scss',
},
},
}],
],
},
},
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]',
},
},
{
loader: 'postcss-loader',
options: {
plugins: () => [
postcssModules({
getJSON: (fileName, json) => {
const cssFileName = fileName.replace(/\.scss$/, '.css');
const cssModuleMap = {};
Object.keys(json).forEach((key) => {
cssModuleMap[key] = json[key].replace(/\$/g, '_');
});
const cssModuleSource = `module.exports = ${JSON.stringify(cssModuleMap)};`;
fs.writeFileSync(cssFileName, cssModuleSource);
},
}),
],
},
},
],
}),
},
],
},
};
在此示例中,Webpack将首先使用postcss-modules插件来处理CSS文件。插件将生成一个映射,将原始类名映射到唯一的类名。然后,用唯一的类名替换模块中的原始类名,并将CSS类名映射到生成的类名。
在Babel的配置中,使用react-css-modules插件来将styleName转换为生成的类名。然后,将CSS类名映射到生成的类名。由于类名已更改,Babel插件将生成的类名转换为className,并将其应用