期望達到的效果
import Test from './test.less'; // 這樣的引入需要css modules
import './test.less'; // 這樣的不需要css modules
雖然 css-loader 自帶一些配置可以用來配置是否開啟當前文件cssModule(配置特殊的文件名,路徑等),但是還是覺得沒有上面的那種用起來方便。
參考 umi css module 的實現,源碼:babel-plugin-auto-css-modules,通過寫 Babel 插件,在 import 的 url 上加上參數,webpack 匹配這個參數,進行不同的配置。
這樣的引入方式也可以消除開啟 css module 后,ant design 組件樣式出錯的問題。
Babel 插件
// scripts/plugin/auto-css-modules.js
const { extname } = require('path');
const CSS_EXTNAMES = ['.css', '.scss', '.sass', '.less'];
module.exports = () => {
return {
visitor: {
ImportDeclaration(path) {
const { specifiers, source } = path.node;
const { value } = source;
if (specifiers.length > 0 && CSS_EXTNAMES.includes(extname(value))) {
source.value = `${value}?css_modules`; // 在路徑末尾加上 css_modules 用於 webpack 匹配該文件,如 import Test from './test.less'; 變成 import Test from './test.less?css_modules';
}
},
},
};
};
在 .babelrc
中引入插件
{
"presets": [
"@babel/preset-react",
"@babel/preset-env",
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties",
"lodash",
"./scripts/plugin/auto-css-modules.js", // 引入插件
["import", {
"libraryName": "antd",
"libraryDirectory": "es",
"style": "css"
}]
]
}
在 webpack 中進行配置
聲明兩個不同的loader配置
// 未開啟 css module 的 loader
const cssLoader = [
'style-loader',
!isEnvDevelopment && {
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
],
},
},
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
},
},
];
// 開啟 css module 的 loader
const cssModulesLoader = JSON.parse(JSON.stringify(cssLoader));
cssModulesLoader[2] = {
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]_[hash:base64:5]',
},
},
};
webpack rules 配置:
module: {
rules: [
{
test: /\.(css|less)$/,
oneOf: [
{
resourceQuery: /css_modules/, // 只要匹配到了這個,就是用css modules,
use: cssModulesLoader.filter(Boolean),
},
{
use: cssLoader.filter(Boolean),
},
],
},
]
}
這樣配置后,就可以在項目中查看具體的效果了。。。。。