[轉] 使用babel-plugin-react-css-modules簡化CSS Modules的使用
阿新 • • 發佈:2018-05-11
麻煩 ash table 項目 引用 con sets name 源碼 的JSON格式已經不夠了(無法表達函數),因此我們要把
在我們的產品中,均使用CSS Modules來作為樣式解決方案,大致的代碼是這樣的:
import React from ‘react‘;
import styles from ‘./table.css‘;
export default class Table extends React.Component {
render () {
return <div className={styles.table}>
<div className={styles.row}>
<div className={styles.cell}>A0</div>
<div className={styles.cell}>B0</div>
</div>
</div>;
}
}
但這裏顯然存在一些細節上的麻煩:
- 引入樣式時額外增加了一個
styles
變量 - 需要不斷寫
styles.xxx
,重復代碼
babel-plugin-react-css-modules
插件可以一定程度上緩解這些問題,使代碼變為:
import React from ‘react‘;
import ‘./table.css‘;
export default class Table extends React.Component {
render () {
return <div styleName=‘table‘>
<div styleName=‘row‘>
<div styleName=‘cell‘>A0</div>
<div styleName=‘cell‘>B0</div>
</div>
</div>;
}
}
難點
- 我們的產品使用LESS而非原生的CSS來編寫樣式
- 為了生成的類名更漂亮,我們使用CSS Modules用了一個自定義的
getLocalIdent
實現 - 與webpack的整合可能存在一些難點
解決方案
安裝依賴
npm i --save babel-plugin-react-css-modules
npm i --save-dev postcss-less
需要註意的是,babel-plugin-react-css-modules
有一個運行時依賴,所以用--save
安裝比較好。而postcss-less
則用於解析LESS的語法
調整構建配置
因為有一個自定義的生成類名的函數,所以原有的.babelrc
.babelrc
的配置移到babel-loader
的options
裏去
在完成移動後,再向其中添加babel-plugin-react-css-modules
這一插件,在這個過程中將生成類名的函數抽象出來:
const generateScopedName = (name, filename) => {
const hash = hasha(filename + name, {algorithm: ‘md5‘});
const basename = path.basename(filename, ‘.less‘);
return `${dashCase(basename)}-${name}-${hash.slice(0, 5)}`;
};
exports.babel = {
loader: ‘babel-loader‘,
options: {
cacheDirectory: true,
presets: [
// ...預置集
],
plugins: [
// ...其它插件
[
‘react-css-modules‘,
{
context: path.join(__dirname, ‘..‘),
exclude: ‘node_modules‘,
filetypes: {
‘.less‘: {
syntax: ‘postcss-less‘
}
},
generateScopedName: generateScopedName
}
]
]
}
};
以上文件為webpack/loaders.js
,相關的配置基本不用修改,原樣使用就行。如果這些代碼的位置不同,將其中的context
配置修改一下,對應至項目根目錄就行。
然後調整一下CSS Modules相關的loader的配置,復用generateScopedName
函數:
exports.cssModules = {
loader: ‘css-loader‘,
options: {
sourceMap: development,
modules: true,
importLoaders: true,
camelCase: ‘dashes‘,
getLocalIdent({resourcePath}, localIdentName, localName) {
return generateScopedName(localName, resourcePath);
}
}
};
修改一些源碼
需要特別註意:所有從.js
中引用.less
的代碼,都不可以依賴webpack的resolve.modules
配置,只能寫相對路徑了。即原來寫import ‘common/less/global.less‘
要改成import ‘./common/less/global.less‘
隨後按著喜好將已經用了className
的地方慢慢改成styleName
就行。
[轉] 使用babel-plugin-react-css-modules簡化CSS Modules的使用