本文主要是基于webpack+es6+react關于css module腳手架的搭建》景希可以從css_module_demo下載相關案例无午,本文擬從4種可能的情形配置啟動css_module。
css_module
css module最簡單的情形暴备,只需要在css-loader啟動css module配置即可。
webpack css-loader
module: {
rules: [{
test: [/\.js$/, /\.jsx$/, /\.es6$/],
include: [
path.resolve(__dirname, 'src'),
],
use: {
loader: "babel-loader"
},
}, {
test: [/\.css/],
exclude: path.resolve(__dirname, 'src/styles/global'),
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]-[hash:base64:5]'
}
}
]
}, {
test: [/\.css/],
include: path.resolve(__dirname, 'src/styles/global'),
use: [
'style-loader',
'css-loader'
]
}]
},
一般項目中们豌,會有normalize.css或者global.css全局css樣式涯捻,此時若不需要處理,可以配置兩種css的管理方式望迎。具體的使用方法障癌,可參照css_module_demo demo1的配置。
css_module + less\scss
若需要配合less辩尊、scss編輯器涛浙,配置與css-loader類似,在css摄欲、less相關配置中設置如下即可.
...
{
test: [/\.css$/, /\.less$/],
exclude: path.resolve(__dirname, 'src/styles/global'),
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]-[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: (loader) => [
require('postcss-import')({ root: loader.resourcePath }),
require('postcss-cssnext')(),
require('autoprefixer')(),
require('cssnano')()
]
}
},
'less-loader'
]
}, {
test: [/\.css$/, /\.less$/],
include: path.resolve(__dirname, 'src/styles/global'),
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: (loader) => [
require('postcss-import')({ root: loader.resourcePath }),
require('postcss-cssnext')(),
require('autoprefixer')(),
require('cssnano')()
]
}
},
'less-loader'
]
}
...
這樣我就可以使用less的功能了轿亮,如我們在app.less中
.global {
text-align: left;
font-size: 20px;
composes: box from "../styles/views/layout.less";
.title {
font-size: 22px;
color: red;
}
.title:before {
content: 'before i come'
}
.title:hover {
font-size: 40px;
}
}
但是css module中,不能在子選擇器中使用compose胸墙,如我們在title中定義composes
.global {
text-align: left;
font-size: 20px;
composes: box from "../styles/views/layout.less";
.title {
font-size: 22px;
composes: heading from "../styles/views/typography.less";
color: red;
}
.title:before {
content: 'before i come'
}
.title:hover {
font-size: 40px;
}
}
會提示類似如下的錯誤
ERROR in ./node_modules/.0.28.7@css-loader?{"modules":true,"localIdentName":"[name]__[local]-[hash:base64:5]"}!./node_modules/.2.0.8@postcss-loader/lib?{"ident":"postcss"}!./node_modules/.4.0.5@less-loader/dist/cjs.js!./src/components/app.less
Module build failed: Error: composition is only allowed when selector is single :local class name not in ":local(.global) :local(.title)"
css module作者在issues/261中提到“Composition works differently to mixins. It does not mutates rules, just concatenates names.”
css_module + react-css-modules
在每個樣式中都是style.*中的形式比較麻煩哀托,可以使用react-css-modules解決這種問題。例如在app.js中
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import CSSModules from 'react-css-modules';
import { Link } from 'react-router-dom';
import styles from './app.less'
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div styleName='global'>
<h1 styleName='title'>css module test case</h1>
<ul role="nav" styleName='nav'>
<li><Link to="/CompositionOverrides">CompositionOverrides</Link></li>
<li><Link to="/GlobalSelectors">GlobalSelectors</Link></li>
<li><Link to="/ScopedAnimations">ScopedAnimations</Link></li>
<li><Link to="/ScopedSelectors">ScopedSelectors</Link></li>
<li><Link to="/StyleVariantA">StyleVariantA</Link></li>
</ul>
{this.props.children}
</div>
);
}
}
export default CSSModules(App, styles)
react-css-modules缺點是是需要運行時的依賴劳秋,而且需要在運行時才獲取className仓手,性能損耗大。在比較大的項目中玻淑,會導致較大的延遲嗽冒。那么這個問題怎么解決那,可以使用bable-plugins-react-css-modules 把className獲取前置到編譯階段补履。
css_module + bable-plugins-react-css-modules
bable-plugins-react-css-modules與react-css-modules是同一個作者開發(fā)的工具添坊,bable-plugins-react-css-modules相對于react-css-modules,在性能方面有了較大的提高箫锤。
bable-plugins-react-css-modules有兩種配置方式贬蛙,一是配置在webpack.config.js雨女,二是配置在.babelrc中,本文采取的方式是配置在webpack.config.js中阳准。
...
{
test: [/\.js$/, /\.jsx$/, /\.es6$/],
include: [
path.resolve(__dirname, 'src'),
],
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
plugins: [
[ "react-css-modules", {
context: path.resolve(__dirname, "src"),
"generateScopedName": "[path][name]__[local]--[hash:base64:5]"
}]
]
}
},
}
...
總結
css module具有靈活性氛堕、易移植的優(yōu)點,可以配合less野蝇、scss等多種css編譯器使用讼稚。本文依賴于webpack css-loader,配置了css module绕沈、css module + less\scss锐想、css module+react-css-modules、css module + babel-plugin-react-css-modules等四種css_module使用方式乍狐。