在我们的产品中,均使用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>;
}
}

但这里显然存在一些细节上的麻烦:

  1. 引入样式时额外增加了一个styles变量
  2. 需要不断写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>;
}
}

难点

  1. 我们的产品使用LESS而非原生的CSS来编写样式
  2. 为了生成的类名更漂亮,我们使用CSS Modules用了一个自定义的getLocalIdent实现
  3. 与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的JSON格式已经不够了(无法表达函数),因此我们要把.babelrc的配置移到babel-loaderoptions里去

在完成移动后,再向其中添加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的使用的更多相关文章

  1. css模块化及CSS Modules使用详解

    什么是css模块化? 为了理解css模块化思想,我们首先了解下,什么是模块化,在百度百科上的解释是,在系统的结构中,模块是可组合.分解和更换的单元.模块化是一种处理复杂系统分解成为更好的可管理模块的方 ...

  2. Angular Vue React 框架中的 CSS

    框架中的 CSS Angular Vue React 三大框架 Angular Vue 内置样式集成 React 一些业界实践 Angular Angular . js (1.x):没有样式集成能力 ...

  3. 重温 Webpack, Babel 和 React

    开始之前 在书写文章之前,我假设大家已经有了 JavaScript,Node 包管理工具,Linux 终端操作 这些基本技能,接下来,我将一步一步指引大家从头搭建一个 React 项目 最终实现的效果 ...

  4. 使用webpack、babel、react、antdesign配置单页面应用开发环境

    这是Webpack+React系列配置过程记录的第一篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ...

  5. webpack+babel+ES6+react环境搭建

    webpack+babel+ES6+react环境搭建 步骤: 1 创建项目结构 注意: 先创建一个项目目录  react  这个名字自定义,然后进入到这个目录下面 mkdir app //创建app ...

  6. babel plugin和presets是什么,怎么用?

    https://www.fullstackreact.com/articles/what-are-babel-plugins-and-presets/ 当开发react或者vuejs app时,开发者 ...

  7. React项目 - 几种CSS实践

    前言团队在使用react时,不断探索,使用了很多不同的css实现方式,此篇blog总结了,react项目中常见的几种css解决方案:inline-style/radium/style-componen ...

  8. 经验分享:使用 Restyle.js 简化 CSS 预处理

    Andrea Giammarchi的restyle.js是一个新的,基于JavaScript的CSS预处理器,能够运行在服务端(通过Node.js)或者浏览器中.它宣称自己是“一种简化的CSS方法”, ...

  9. Webpack 2 视频教程 012 - 理解Webpack 中的 CSS 作用域与 CSS Modules

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  10. 简单 babel plugin 开发-使用lerna 工具

    babel在现在的web 应用开发上具有很重要的作用,帮助我们做了好多事情,同时又有 比较多的babel plugin 可以解决我们实际开发上的问题. 以下只是学习下如果编写一个简单的babel pl ...

随机推荐

  1. Linux 网卡驱动学习(五)(收发包具体过程)【转】

    转自:https://blog.csdn.net/xy010902100449/article/details/47362787 版权声明:本文为博主原创文章,未经博主允许不得转载. https:// ...

  2. python3+requests库框架设计05-unittest单元测试框架

    unittest单元测试框架,主要由四部分组成:测试固件.测试用例.测试套件.测试执行器 测试固件(test fixture) 测试固件有两部分,执行测试前的准备部分setUp(),测试执行完后的清扫 ...

  3. Mysql数据库远程链接、权限修改、导入导出等基本操作

    一.连接MySQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL. 首先在打开DOS窗口,然后进入目录 mysqlbin,再键入命令mysql -ur ...

  4. ffmpeg-201701[10,16,21,23,25]-bin.7z

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 5 屏幕横向放大 20 像素 6 屏幕横向缩小 20 像素 S 下一帧 [ -2秒 ] +2 ...

  5. bootstrap4简单使用和入门03-响应式布局

    响应式布局的原理 页面源码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  6. 阿里服务器配置swap

    说明:阿里服务器安装系统之后,默认swap为0 .该篇是阿里服务器上配置swap 的过程记录: 1.进入目录 cd /var/ 2.获取要增加的SWAP文件块(这里以1GB为例,count = 102 ...

  7. Linux i2c 读写程序

    /* This software uses a BSD license. Copyright (c) 2010, Sean Cross / chumby industriesAll rights re ...

  8. j2cache笔记

    初步理解 eg: https://my.oschina.net/javayou https://my.oschina.net/tinyframework/blog/538363?p=2 https:/ ...

  9. js——事件冒泡与捕获小例子

    布局代码 #outer{ width: 300px; height: 300px; background: red; } #inner{ width: 200px; height: 200px; ba ...

  10. Confluence 6 自定义默认空间内容

    中文标题[自定义默认空间内容] Confluence 管理员 可以编辑用于创建主页和新站点的模板.默认的内容将会在新空间创建后的主页上显示出来.这个与站点空间,个人空间和空间蓝图的模板是不同的. 模板 ...