用法教程

全局CSS的终结(狗带)

2015/10/24 · CSS ·
全局

初稿出处: Mark
Dalgleish   译文出处:AlloyTeam   

CSS类名总是功效在相同的全局功效域里面。

其它一个跟CSS有长日子打交道的开发者,都不得不承受CSS那所有入侵性的全局特性,鲜明地那是一种文档流时代的布置模型。而对此前日现代web应用,更应有积极提出一种更周全的体裁环境。

每一个CSS类名都有可能与任何元素爆发的意想不到副成效,又或者发生争执。更令人吃惊的是,大家的class的功力说不定在大局功能域的互相影响下(原文那里比喻为全局唯一性战争),最后在页面上发生很少的成效照旧根本没有意义。

任曾几何时候我们转移一个CSS文件,大家都须要审慎地考虑全局环境是还是不是暴发争持。没有其他前端技术是亟需这么之多的正式和自律,而那只是是为了有限帮助最低级其他可维护性。

 

、、、

 

但大家不可能一直那样下来。是时候摆脱那种全局样式的折磨。开启局地CSS的一世!

“在其余语言,全局环境的修改需求转移的代码很少”

在javascript的社区中,感谢Browserify,Webpack和JSPM,让我们的代码变得模块化,每个模块有强烈的借助及其输出的API。但是,不知怎么的,CSS视乎总时被忽略掉。

咱俩中许多人,包蕴自己要好,一直选择CSS工作这么长日子,大家都没有发觉不够局部性功效域,是一种难点。因为从没浏览器厂商的第一救助下大家也可以解决。即使那样,大家如故需求等待着,一大半用户能使用上浏览器的ShadowDOM的支持。

在大局成效域难点上,我们早已选择一文山会海的命名规范来编码。想OOCSS, SMACSS,BEM和SUIT,每一个都提供着一种艺术模拟健全的功用域规则,达到幸免命名顶牛效果。

即使如此驯服CSS无疑是一个宏伟的升华,但这一个方法都没有缓解大家样式表上实在的题材。无论大家挑选哪个规范,我们依旧被卡在大局类名上。

但,在二零一五年的4月22号将会爆发转移。

、、、
正如我辈原先的一篇小说涉及到——“Block,Element,修改你的JavaScript组件”——大家得以应用Webpack把我们的CSS
用作一种JavaScript模块来引用。假使那听起来很陌生,去读读这篇作品会是一个good
idea,以免你错失接下来要讲的内容。

使用Webpack的css-loader,引用一个零部件的CSS如下:

JavaScript

require(‘./MyComponent.css’);

1
require(‘./MyComponent.css’);

乍一看,那很想获得,大家引用的是CSS而不是JavaScript

日常,一个require引入的应当提供部分片段功效域。若是或不是,分明低会暴发全局成效域的副效用,那是一种鸠拙的设计。而CSS的全局成效域特性,却一定爆发这么的副成效。

因而我们在思索

、、、

2015年4月22日,Tobias
Koppers这位对Webpack孜孜不倦的代码提交者,提交了一个css-loader新特性的版本提交。当时叫placeholder,而后天叫local-scope。那些特性允许大家输出classname从大家的CSS到利用中的JavaScript代码。

简简单单,上面那种写法:

JavaScript

requrie(‘./MyComponent.css’);

1
requrie(‘./MyComponent.css’);

咱俩改为

JavaScript

import styles from ‘./MyComponent.css’;

1
import styles from ‘./MyComponent.css’;

探访大家导出的CSS是何等的,我们的代码大约如下:

:local(.foo){ color: red; } :local(.bar){ color:blue; }

1
2
3
4
5
6
:local(.foo){
    color: red;
}
:local(.bar){
    color:blue;
}

在地点的例证中我们采取css-loader的定制的语法  :local(.idntifier) ,输出了七个的标识符,foo和bar。
那么些标识符对应着class
strings,这将用在javascript文件中去。例如,当大家利用React:

import styles from ‘./MyComponent.css’; import React, { Component } from
‘react’; export default class MyComponent extends Component { render() {
return ( <div> <div className={styles.foo}>Foo</div>
<div className={styles.bar}>Bar</div> </div> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
import styles from ‘./MyComponent.css’;
import React, { Component } from ‘react’;
export default class MyComponent extends Component {
  render() {
    return (
      <div>
        <div className={styles.foo}>Foo</div>
        <div className={styles.bar}>Bar</div>
      </div>
    );
  }
}

驷马难追的是,这几个标识符映射的class strings,在大局作用域上是保障唯一的。
咱俩不再要求给拥有的类名添加冗长的前缀来效仿范围。多个零件可以自定义自己的foo和bar标识符。——不像传统的大局作用域的情势,也不会生出命名冲突。

、、、

非常首要的少数,不得不认可那已经爆发了光辉转变。
咱俩前日更有信念地大胆修改我们的CSS,不用战战兢兢地怕影响其余页面的因素。大家引入了一个到家的功用域情势

全局CSS的利益是,组件间透过通用的class来达到复用的功力——那还可以在有的效能域模型上完结。关键的不一样是,就像大家编码在其余语言上,大家须求显式地引入我们借助的类。假想一下在全局命名环境,大家引入的一些CSS不必要过多。

“编写可保险的CSS现在是值得提倡的,但不是透过谨慎地准守一个命名约定,而是在开发进度中经过单独的包裹”

是因为那些作用域模型,大家把实际的classname的控制权移交给Webpack。幸运的是,那是自我得以安顿的。默许景况下,css-loader会把标识符转换成为hash。
例如:

JavaScript

:local(.foo){….}

1
:local(.foo){….}

 

编译为:

JavaScript

._1rJwx92-gmbvaLiDdzgXiJ { … }

1
._1rJwx92-gmbvaLiDdzgXiJ { … }

在付出环境调试来讲,会带带来一些阻碍。为了令到大家的classes变得越来越有用,我们可在Webpack的config里面安装css-loader的参数,配置class的格式。

JavaScript

loaders: [ … { test: /\.css$/, loader:
‘css?localIdentName=[name]__[local]___[hash:base64:5]’ } ]

1
2
3
4
5
6
7
loaders: [
  …
  {
    test: /\.css$/,
    loader: ‘css?localIdentName=[name]__[local]___[hash:base64:5]’
  }
]

在那两回,大家的foo这一个class会比之前编译的进一步好辨认:

JavaScript

.MyComponent__foo___1rJwx { … }

1
.MyComponent__foo___1rJwx { … }

大家能清晰地看收获标识符的名字,以及他来自哪个组件。使用node_env环境变量,我们能按照开发情势和生产条件布置不相同的class命名模式。

JavaScript

loader: ‘css?localIdentName=’ + ( process.env.NODE_ENV ===
‘development’ ? ‘[name]__[local]___[hash:base64:5]’ :
‘[hash:base64:5]’ )

1
2
3
4
5
loader: ‘css?localIdentName=’ + (
  process.env.NODE_ENV === ‘development’ ?
    ‘[name]__[local]___[hash:base64:5]’ :
    ‘[hash:base64:5]’
)

 

假诺大家发现那一个特性,大家不要犹豫地在大家最新的花色上本地化起来。如若按照常规,大家已经为组件化而使用BEM命名CSS,那真是天作之合。

有趣的是,一种现象很快地冒出了,我们一大半CSS文件里唯有一部差异class:

JavaScript

:local(.backdrop) { … } :local(.root_isCollapsed .backdrop) { … }
:local(.field) { … } :local(.field):focus { … } etc…

1
2
3
4
5
:local(.backdrop) { … }
:local(.root_isCollapsed .backdrop) { … }
:local(.field) { … }
:local(.field):focus { … }
etc…

 

全局性的class仅仅在web应用里面的一小部分,本能地引开出一个重中之重难点:

“假使不需求特殊语法,我们的class默许是区域性的,而让全局性的class须要分裂。怎样?”

假使那样,大家地点的代码就变成如下:

JavaScript

.backdrop { … } .root_isCollapsed .backdrop { … } .field { … }
.field:focus { … }

1
2
3
4
.backdrop { … }
.root_isCollapsed .backdrop { … }
.field { … }
.field:focus { … }

 

即便那class平常会过度模糊,但当他俩转移为css-lodaer的一部分功用域的格式后将会消除这一题材。并且保险了引人注目的模块功效域来使用。

少数景观,我们鞭长莫及幸免全局样式,大家可以一目明白地标Bellamy(Bellamy)个新鲜的大局语法。例如,当样式使用ReactCSSTransitionGroup来生成一个无效力域classes。

.panel :global .transition-active-enter{…}

在这几个例子中,大家不仅是行使本地化方式命名我的模块,大家也命名了一个不在大家的效率域上的大局class。

、、、

一经自身起来调研自己什么落实这一个默许局部化class语法,我们发现到它不会太困难。
为了完成这几个目标,大家推荐PostCSS——一个神奇的工具允许你编写自定义的CSS转换插件。明天最受欢迎的CSS打造工具Autoprefixer实际上是PostCSS插件,同时为一个独门的工具而已。

为让有些CSS正式地使用,我早已开源了一个可观实验性质的插件postcss-local-scope。它依旧在进化,所以在生养环境中运用你须求控制风险。

假诺您采用Webpack,那是分外简单的流水线:挂上postcss-loader和postcss-local-scope在你的CSS营造流程。比起文档,我早就创建了一个示例库——postcss-local-scope-example。里面展现了怎么选拔的例证。
令人激动的是,引入局地功效域仅仅是一个伊始。
让构建工具处理classname有局地隐秘的皇皇影响。从长久来看,大家理应甘休人为的编译器,而是让电脑来优化出口。

“在以后,大家得以在一个最优的编译时间内,自动化找出可采取的体裁,生成可组件之间共享的class”

假诺你品味了一部分CSS,你就回不去了。真正感受过,样式的部分成效性在有着浏览器上运行如常,你会难以忘却的经验。

引入局地作用域对大家处理CSS有重点的的相干反应。命名规范,重用格局,潜在的体制抽离,分包等等,都会平素境遇那种变更的影响。大家无非在此处起首了一些CSS的一代。

通晓那种变更的影响是大家如故须求全力以赴。伴随你有价值的投入和实验,我愿意这是用作一个更大的社区的两次讲话

“参预我们,check出postcss-local-scope-example的代码,眼见为实”

如若你行动了,我认为你会容许那并不浮夸:
全局CSS的生活将会完成,局地CSS才是未来。

 

后记:
二〇一五年七月24日:
postcss-local-scope的早期想法已经被Webpack的托拜厄斯Koppers所收受。那表示改项目已经被弃用了。现在大家早先肯定在css-loader上经过一个module的标志可以援助CSS
Modules。我创设了一个库来演示CSSModules在css-loader上的用法,包含类的延续及效用组件间共享样式等。

1 赞 1 收藏
评论

亚洲必赢官网 1

CSS Modules 用法教程

2016/06/19 · CSS ·
Modules

原稿出处:
阮一峰   

学过网页开发就会驾驭,CSS 不能算编程语言,只是网页样式的一种描述方法。

为了让 CSS
也能适用软件工程措施,程序员想了种种艺术,让它变得像一门编程语言。从最早的Less、SASS,到后来的
PostCSS,再到近日的 CSS in JS,都是为着化解那么些标题。

亚洲必赢官网 2

正文介绍的 CSS Modules
有所分歧。它不是将 CSS
改造成编程语言,而是功效很单纯,只插手了部分效用域和模块爱戴,那正好是网页组件最急需的法力。

从而,CSS Modules
很不难学,因为它的规则少,同时又丰硕有用,可以确保某个组件的体制,不会影响到其他零件。

亚洲必赢官网 3

CSS Modules 入门及 React 中实践

2017/03/25 · CSS ·
React

原稿出处:
AlloyTeam   

CSS Modules 详解及 React 中实践

2016/01/18 · CSS · CSS
Modules,
React

原文出处: pure render –
camsong   

亚洲必赢官网 4

CSS 是前者领域中前行最慢的一块。由于 ES2015/2016 的高速普及和
Babel/Webpack 等工具的迅猛发展,CSS
被远远甩在了后头,渐渐变为大型项目工程化的痛点。也变成了前者走向绝望模块化前务必解决的难点。

CSS 模块化的缓解方案有好多,但重点有两类。一类是干净废弃 CSS,使用 JS 或
JSON
来写样式。Radium,jsxstyle,react-style
属于这一类。优点是能给 CSS 提供 JS
同样强大的模块化能力;缺点是不可能使用成熟的 CSS 预处理器(或后电脑)
Sass/Less/PostCSS,:hover:active
伪类处理起来复杂。另一类是仍旧拔取 CSS,但运用 JS 来保管体制看重,代表是
CSS
Modules。CSS
Modules 能最大化地结合现有 CSS 生态和 JS 模块化能力,API
简洁到几乎零读书开支。发表时照旧编译出单身的 JS 和 CSS。它并不依靠于
React,只要你使用 Webpack,可以在 Vue/Angular/jQuery
中应用。是自家觉得当前最好的 CSS
模块化解决方案。近年来在档次中大批量运用,上面具体享受下进行中的细节和设法。

 

零、示例库

自己为那一个课程写了一个示例库,蕴涵两个Demo。通过它们,你可以轻松学会CSS
Modules。

首先,克隆示例库。

JavaScript

$ git clone

1
$ git clone https://github.com/ruanyf/css-modules-demos.git

下一场,安装依赖。

JavaScript

$ cd css-modules-demos $ npm install

1
2
$ cd css-modules-demos
$ npm install

跟着,就可以运行第二个示范了。

JavaScript

$ npm run demo01

1
$ npm run demo01

开拓浏览器,访问

写在眼前

读文先看此图,能先有个大体概念:

亚洲必赢官网 5

翻阅本文须要 11m 24s。

CSS 模块化遇到了如何难点?

CSS 模块化首要的是要解决好多少个难点:CSS
样式的导入和导出。灵活按需导入以便复用代码;导出时要力所能及隐藏其间功用域,避防导致全局污染。Sass/Less/PostCSS
等持续试图缓解 CSS
编程能力弱的标题,结果它们做的也着实不错,但那并从未缓解模块化最根本的题材。脸书工程师 Vjeux 首先抛出了 React 开发中碰到的一层层 CSS
相关难点。加上我个人的观点,统计如下:

  1. 大局污染

CSS
使用全局拔取器机制来安装样式,优点是便利重写样式。缺点是持有的样式都是大局生效,样式可能被错误覆盖,由此爆发了相当难看的
!important,甚至 inline !important
和复杂性的[挑选器权重计数表](Selectors Level
3),提升犯错几率和拔取资金。Web
Components 标准中的 Shadow DOM
能彻底解决这些标题,但它的做法有些极端,样式彻底局地化,造成外部无法重写样式,损失了灵活性。

  1. 命名混乱

 

是因为全局污染的难题,多个人齐声开发时为了防止样式冲突,拔取器越来越复杂,简单形成分裂的命名风格,很难统一。样式变多后,命名将越发混乱。

  1. 借助于管理不到头

零件应该互相独立,引入一个零部件时,应该只引入它所急需的 CSS
样式。但现在的做法是除了要引入 JS,还要再引入它的 CSS,而且 Saas/Less
很难完毕对种种组件都编译出单身的 CSS,引入所有模块的 CSS 又造成浪费。JS
的模块化已经充足干练,若是能让 JS 来治本 CSS
看重是很好的解决办法。Webpack 的 css-loader 提供了那种能力。

  1. 没辙共享变量

复杂组件要利用 JS 和 CSS 来共同处理体制,就会促成有些变量在 JS 和 CSS
中冗余,Sass/PostCSS/CSS 等都不提供跨 JS 和 CSS 共享变量那种力量。

  1. 代码压缩不到底

由于活动端互联网的不确定性,现在对 CSS
压缩已经到了变态的水准。很多压缩工具为了节约一个字节会把 ’16px’ 转成
‘1pc’。但对很是长的 class 名却无法,力没有用到刀刃上。

下边的题目若是只凭 CSS 自身是心有余而力不足缓解的,即使是透过 JS 来保管 CSS
就很好解决,由此 Vjuex 给出的化解方案是完全的 CSS in
JS,但这一定于完全丢弃CSS,在 JS 中以 Object 语法来写
CSS,估量刚看到的同伴都震惊了。直到出现了 CSS Modules。

 

一、局地功用域

CSS的条条框框都是大局的,任何一个零件的体裁规则,都对任何页面有效。

发生部分作用域的绝无仅有办法,就是选择一个独一无二的class的名字,不会与其余选用重视名。那就是
CSS Modules 的做法。

下边是一个React组件App.js。

JavaScript

import React from ‘react’; import style from ‘./App.css’; export default
() => { return ( <h1 className={style.title}> Hello World
</h1> ); };

1
2
3
4
5
6
7
8
9
10
import React from ‘react’;
import style from ‘./App.css’;
 
export default () => {
  return (
    <h1 className={style.title}>
      Hello World
    </h1>
  );
};

地点代码中,我们将样式文件App.css输入到style对象,然后引用style.title代表一个class。

CSS

.title { color: red; }

1
2
3
.title {
  color: red;
}

营造工具会将类名style.title编译成一个哈希字符串。

XHTML

<h1 class=”_3zyde4l1yATCOkgn-DBWEL”> Hello World </h1>

1
2
3
<h1 class="_3zyde4l1yATCOkgn-DBWEL">
  Hello World
</h1>

App.css也会同时被编译。

JavaScript

._3zyde4l1yATCOkgn-DBWEL { color: red; }

1
2
3
._3zyde4l1yATCOkgn-DBWEL {
  color: red;
}

那样一来,这么些类名就成为独一无二了,只对App组件有效。

CSS Modules
提供种种用法教程。插件,接济不一致的营造工具。本文使用的是
Webpack
的css-loader插件,因为它对
CSS Modules 的扶助最好,而且很不难接纳。顺便说一下,即使你想学
Webpack,可以阅读我的教程Webpack-Demos。

上面是其一示例的webpack.config.js。

JavaScript

module.exports = { entry: __dirname + ‘/index.js’, output: {
publicPath: ‘/’, filename: ‘./bundle.js’ }, module: { loaders: [ {
test: /.jsx?$/, exclude: /node_modules/, loader: ‘babel’, query: {
presets: [‘es2015’, ‘stage-0’, ‘react’] } }, { test: /.css$/, loader:
“style-loader!css-loader?modules” }, ] } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module.exports = {
  entry: __dirname + ‘/index.js’,
  output: {
    publicPath: ‘/’,
    filename: ‘./bundle.js’
  },
  module: {
    loaders: [
      {
        test: /.jsx?$/,
        exclude: /node_modules/,
        loader: ‘babel’,
        query: {
          presets: [‘es2015’, ‘stage-0’, ‘react’]
        }
      },
      {
        test: /.css$/,
        loader: "style-loader!css-loader?modules"
      },
    ]
  }
};

地点代码中,关键的一行是style-loader!css-loader?modules,它在css-loader后边加了一个查询参数modules,表示打开
CSS Modules 成效。

前些天,运行这么些Demo。

JavaScript

$ npm run demo01

1
$ npm run demo01

打开
,能够看来结果,h1标题突显为革命。

CSS Modules介绍

CSS Modules是怎么着事物吧?首先,让我们从官方文档入手:
GitHub – css-modules/css-modules: Documentation about
css-modules

A CSS Module is a CSS file in which all class names and animation
names are scoped locally by default.
CSS模块就是颇具的类名都唯有一些功效域的CSS文件。

从而CSS
Modules既不是法定正式,也不是浏览器的特色,而是在营造步骤(例如使用Webpack或Browserify)中对CSS类名拔取器限定成效域的一种办法(通过hash完成类似于命名空间的不二法门)。

It doesn’t really matter in the end (although shorter class names mean
shorter stylesheets) because the point is that they are dynamically
generated, unique, and mapped to the correct
styles.在选择CSS模块时,类名是动态变化的,唯一的,并精确对应到源文件中的各样类的体裁。

这也是落到实处样式作用域的法则。它们被限定在特定的模版里。例如咱们在buttons.js里引入buttons.css文件,并使用.btn的体裁,在其余零件里是不会被.btn影响的,除非它也引入了buttons.css.

可我们是由于什么样目的把CSS和HTML文件搞得这么零碎呢?大家为何要运用CSS模块呢?

CSS Modules 模块化方案

亚洲必赢官网 6

CSS Modules 内部通过 [ICSS](css-modules/icss ·
GitHub)
来解决体制导入和导出那五个难点。分别对应 :import:export
八个新增的伪类。

JavaScript

:import(“path/to/dep.css”) { localAlias: keyFromDep; /* … */ }
:export { exportedKey: exportedValue; /* … */ }

1
2
3
4
5
6
7
8
:import("path/to/dep.css") {
  localAlias: keyFromDep;
  /* … */
}
:export {
  exportedKey: exportedValue;
  /* … */
}

 

但一贯运用那多个重大字编程太费事,实际项目中很少会直接行使它们,大家须要的是用
JS 来治本 CSS 的能力。结合 Webpack 的 css-loader 后,就足以在 CSS
中定义样式,在 JS 中导入。
启用 CSS Modules

JavaScript

// webpack.config.js
css?modules&localIdentName=[name]__[local]-[hash:base64:5]

1
2
// webpack.config.js
css?modules&localIdentName=[name]__[local]-[hash:base64:5]

加上 modules 即为启用,localIdentName 是安装生成样式的命名规则。

JavaScript

/* components/Button.css */ .normal { /* normal 相关的有着样式 */ }
.disabled { /* disabled 相关的装有样式 */ }

1
2
3
/* components/Button.css */
.normal { /* normal 相关的所有样式 */ }
.disabled { /* disabled 相关的所有样式 */ }

JavaScript

// components/Button.js import styles from ‘./Button.css’;
console.log(styles); buttonElem.outerHTML = `<button
class=${styles.normal}>Submit</button>`

1
2
3
4
// components/Button.js
import styles from ‘./Button.css’;
console.log(styles);
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

生成的 HTML 是

<button class=”button–normal-abc53″>Submit</button>

1
<button class="button–normal-abc53">Submit</button>

 

注意到 button--normal-abc53 是 CSS Modules 按照 localIdentName
自动生成的 class 名。其中的 abc53
是依据给定算法生成的种类码。经过这么模糊处理后,class
名基本就是绝无仅有的,大大降低了档次中样式覆盖的几率。同时在生育条件下修改规则,生成更短的
class 名,可以坚实 CSS 的压缩率。

上例中 console 打印的结果是:

JavaScript

Object { normal: ‘button–normal-abc53’, disabled:
‘button–disabled-def886’, }

1
2
3
4
Object {
  normal: ‘button–normal-abc53’,
  disabled: ‘button–disabled-def886’,
}

CSS Modules 对 CSS 中的 class 名都做了处理,使用对象来保存原 class
和歪曲后 class 的应和关系。

经过那一个概括的处理,CSS Modules 完毕了以下几点:

  • 拥有样式都是 local 的,解决了命名顶牛和全局污染难点
  • class 名生成规则配置灵活,可以此来压缩 class 名
  • 只需引用组件的 JS 就能搞定组件所有的 JS 和 CSS
  • 依然是 CSS,大致 0 学费

体制默许局地

拔取了 CSS Modules 后,就一定于给各类 class 名外加加了一个
:local,以此来贯彻样式的局地化,即使您想切换到全局形式,使用相应的
:global

:local:global 的分别是 CSS Modules 只会对 :local 块的 class
样式做 localIdentName 规则处理,:global 的体制编译后不变。

JavaScript

.normal { color: green; } /* 以上与下部等价 */ :local(.normal) {
color: green; } /* 定义全局样式 */ :global(.btn) { color: red; } /*
定义多少个全局样式 */ :global { .link { color: green; } .box { color:
yellow; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.normal {
  color: green;
}
 
/* 以上与下面等价 */
:local(.normal) {
  color: green;
}
 
/* 定义全局样式 */
:global(.btn) {
  color: red;
}
 
/* 定义多个全局样式 */
:global {
  .link {
    color: green;
  }
  .box {
    color: yellow;
  }
}

Compose 来整合样式

对此样式复用,CSS Modules 只提供了唯一的章程来拍卖:composes 组合

JavaScript

/* components/Button.css */ .base { /* 所有通用的样式 */ } .normal {
composes: base; /* normal 别的样式 */ } .disabled { composes: base;
/* disabled 其余样式 */ }

1
2
3
4
5
6
7
8
9
10
11
12
/* components/Button.css */
.base { /* 所有通用的样式 */ }
 
.normal {
  composes: base;
  /* normal 其它样式 */
}
 
.disabled {
  composes: base;
  /* disabled 其它样式 */
}

JavaScript

import styles from ‘./Button.css’; buttonElem.outerHTML = `<button
class=${styles.normal}>Submit</button>`

1
2
3
import styles from ‘./Button.css’;
 
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

生成的 HTML 变为

<button class=”button–base-fec26
button–normal-abc53″>Submit</button>

1
<button class="button–base-fec26 button–normal-abc53">Submit</button>

由于在 .normal 中 composes 了 .base,编译后会 normal 会变成两个class。

composes 仍是可以构成外部文件中的样式。

JavaScript

/* settings.css */ .primary-color { color: #f40; } /*
components/Button.css */ .base { /* 所有通用的样式 */ } .primary {
composes: base; composes: primary-color from ‘./settings.css’; /*
primary 其它样式 */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
/* settings.css */
.primary-color {
  color: #f40;
}
 
/* components/Button.css */
.base { /* 所有通用的样式 */ }
 
.primary {
  composes: base;
  composes: primary-color from ‘./settings.css’;
  /* primary 其它样式 */
}

 

对此多数门类,有了 composes 后一度不再要求Sass/Less/PostCSS。但即使您想用的话,由于 composes 不是正统的 CSS
语法,编译时会报错。就只好动用预处理器自己的语法来做样式复用了。
class 命名技巧

CSS Modules 的命名规范是从 BEM 扩充而来。BEM 把体制名分为 3
个级别,分别是:

  • Block:对应模块名,如 Dialog
  • Element:对应模块中的节点名 Confirm Button
  • Modifier:对应节点相关的情景,如 disabled、highlight

综上,BEM 最后得到的 class 名为
dialog__confirm-button--highlight。使用双标志 __--
是为了和区块内单词间的相间符区分开来。就算看起来有点出人意料,但 BEM
被这些多的大型项目和团队选择。大家进行下来也很认可那种命名格局。

CSS Modules 中 CSS 文件名正要对应 Block 名,只须要再考虑 Element 和
Modifier。BEM 对应到 CSS Modules 的做法是:

JavaScript

/* .dialog.css */ .ConfirmButton–disabled { /* … */ }

1
2
3
4
/* .dialog.css */
.ConfirmButton–disabled {
  /* … */
}

您也得以不依照完全的命名规范,使用 camelCase 的写法把 Block 和 Modifier
放到一起:

JavaScript

/* .dialog.css */ .disabledConfirmButton { }

1
2
3
/* .dialog.css */
.disabledConfirmButton {
}

哪些促成CSS,JS变量共享

注:CSS Modules 中没有变量的概念,那里的 CSS 变量指的是 Sass 中的变量。

下边提到的 :export 关键字可以把 CSS 中的 变量输出到 JS
中。上边演示怎么样在 JS 中读取 Sass 变量:

JavaScript

/* config.scss */ $primary-color: #f40; :export { primaryColor:
$primary-color; }

1
2
3
4
5
6
/* config.scss */
$primary-color: #f40;
 
:export {
  primaryColor: $primary-color;
}

 

JavaScript

/* app.js */ import style from ‘config.scss’; // 会输出 #F40
console.log(style.primaryColor);

1
2
3
4
5
/* app.js */
import style from ‘config.scss’;
 
// 会输出 #F40
console.log(style.primaryColor);

二、全局成效域

CSS Modules
允许利用:global(.className)的语法,声爱他美(Aptamil)个大局规则。凡是那样注明的class,都不会被编译成哈希字符串。

App.css加盟一个大局class。

JavaScript

.title { color: red; } :global(.title) { color: green; }

1
2
3
4
5
6
7
.title {
  color: red;
}
 
:global(.title) {
  color: green;
}

App.js行使普通的class的写法,就会引用全局class。

JavaScript

import React from ‘react’; import styles from ‘./App.css’; export
default () => { return ( <h1 className=”title”> Hello World
</h1> ); };

1
2
3
4
5
6
7
8
9
10
import React from ‘react’;
import styles from ‘./App.css’;
 
export default () => {
  return (
    <h1 className="title">
      Hello World
    </h1>
  );
};

运作那些示例。

JavaScript

$ npm run demo02

1
$ npm run demo02

打开

CSS Modules
还提供一种显式的局地效能域语法:local(.className),等同于.className,所以地方的App.css也足以写成下边这样。

JavaScript

:local(.title) { color: red; } :global(.title) { color: green; }

1
2
3
4
5
6
7
:local(.title) {
  color: red;
}
 
:global(.title) {
  color: green;
}

干什么我们要求CSS模块化

CSS Modules 使用技巧

CSS Modules 是对现有的 CSS
做减法。为了追求**粗略可控**,作者指出按照如下原则:

  • 不接纳选取器,只行使 class 名来定义样式
  • 不层叠多少个 class,只行使一个 class 把所有样式定义好
  • 不嵌套
  • 使用 composes 组合来落到实处复用

上边两条原则相当于削弱了体制中最灵敏的局地,初使用者很难接受。第一条实施起来难度不大,但第二条假如模块状态过多时,class
数量将倍增上升。

毫无疑问要知道,上边之所以称为提议,是因为 CSS Modules
并不强制你肯定要这么做。听起来有点格格不入,由于多数 CSS
项目设有深厚的野史遗留难题,过多的限制就表示增添迁移费用和与外部同盟的财力。初期使用中势必须要有的低头。幸运的是,CSS
Modules 那一点做的很好:

1. 一旦本身对一个元素运用四个 class 呢?

没难题,样式仍然生效。

2. 如何自身在一个 style 文件中运用同名 class 呢?

没难题,那个同名 class 编译后虽说可能是随机码,但仍是同名的。

3. 假使本身在 style 文件中利用了 id 采用器,伪类,标签选拔器等啊?

没难点,所有那么些选取器将不被转移,原封不动的出现在编译后的 css
中。也就是说 CSS Modules 只会更换 class 名相关样式。

但注意,上面 3 个“即使”尽量不要暴发

三、定制哈希类名

css-loader默许的哈希算法是[hash:base64],这会将.title编译成._3zyde4l1yATCOkgn-DBWEL那样的字符串。

webpack.config.js内部可以定制哈希字符串的格式。

JavaScript

module: { loaders: [ // … { test: /.css$/, loader:
“style-loader!css-loader?modules&localIdentName=[path][name]—[local]—[hash:base64:5]”
}, ] }

1
2
3
4
5
6
7
8
9
module: {
  loaders: [
    // …
    {
      test: /.css$/,
      loader: "style-loader!css-loader?modules&amp;localIdentName=[path][name]—[local]—[hash:base64:5]"
    },
  ]
}

运转这些示例。

JavaScript

$ npm run demo03

1
$ npm run demo03

你会发现.title被编译成了demo03-components-App—title—GpMto。

CSS全局功能域难点

CSS的规则都是大局的,任何一个组件的样式规则,都对整体页面有效。相信写css的人都会遇上样式冲突(污染)的题材。

于是一般这么做(小编都做过):
* class命名写长一点吧,下跌争辩的概率
* 加个父元素的选拔器,限制范围
* 重新命名个class吧,相比保证

为此亟待解决的标题就是css局地成效域幸免全局样式争执(污染)的难题

CSS Modules 结合 React 实践

className 处间接行使 css 中 class 名即可。

JavaScript

.root {} .confirm {} .disabledConfirm {}

1
2
3
.root {}
.confirm {}
.disabledConfirm {}

import classNames from ‘classnames’; import styles from ‘./dialog.css’;
export default class Dialog extends React.Component { render() { const
cx = classNames({ confirm: !this.state.disabled, disabledConfirm:
this.state.disabled }); return <div className={styles.root}> <a
className={styles.disabledConfirm}>Confirm</a> … </div>
} }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import classNames from ‘classnames’;
import styles from ‘./dialog.css’;
 
export default class Dialog extends React.Component {
  render() {
    const cx = classNames({
      confirm: !this.state.disabled,
      disabledConfirm: this.state.disabled
    });
 
    return <div className={styles.root}>
      <a className={styles.disabledConfirm}>Confirm</a>
      …
    </div>
  }
}

专注,一般把组件最外层节点对应的 class 名称为 root。那里运用了
[classnames](https://www.npmjs.com/package/classnames)
库来操作 class 名。

万一你不想频繁的输入 styles.**,可以试一下
[react-css-modules](gajus/react-css-modules ·
GitHub),它经过高阶函数的花样来避免再一次输入
styles.**

CSS Modules 结合历史遗留项目执行

好的技能方案除了成效强大炫酷,还要能到位现有项目能平滑迁移。CSS Modules
在那或多或少上显示的相当灵活。

外表怎么样覆盖局地样式

当生成混淆的 class 名后,能够缓解命名争辩,但因为无法预言最后 class
名,不可以透过一般拔取器覆盖。大家后天项目中的实践是可以给组件关键节点加上
data-role 属性,然后经过质量选拔器来覆盖样式。

// dialog.js return <div className={styles.root}
data-role=’dialog-root’> <a className={styles.disabledConfirm}
data-role=’dialog-confirm-btn’>Confirm</a> … </div>

1
2
3
4
5
// dialog.js
  return <div className={styles.root} data-role=’dialog-root’>
      <a className={styles.disabledConfirm} data-role=’dialog-confirm-btn’>Confirm</a>
      …
  </div>

 

JavaScript

/* dialog.css */ [data-role=”dialog-root”] { // override style }

1
2
3
4
/* dialog.css */
[data-role="dialog-root"] {
  // override style
}

因为 CSS Modules 只会变卦类接纳器,所以那边的性质选取器不须求添加
:global

怎么与全局样式共存

前者项目不可幸免会引入 normalize.css 或其余一类全局 css 文件。使用
Webpack 可以让全局样式和 CSS Modules
的一些样式和谐共存。上面是大家项目中使用的 webpack 部分布置代码:

JavaScript

文章权归小编所有。 商业转发请联系小编得到授权,非商业转发请注脚出处。
小编:camsong 链接:
来源:知乎 // webpack.config.js 局部 module: { loaders: [{ test:
/\.jsx?$/, loader: ‘babel’ }, { test: /\.scss$/, exclude:
path.resolve(__dirname, ‘src/styles’), loader:
‘style!css?modules&localIdentName=[name]__[local]!sass?sourceMap=true’
}, { test: /\.scss$/, include: path.resolve(__dirname, ‘src/styles’),
loader: ‘style!css!sass?sourceMap=true’ }] }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:camsong
链接:http://zhuanlan.zhihu.com/purerender/20495964
来源:知乎
 
// webpack.config.js 局部
module: {
  loaders: [{
    test: /\.jsx?$/,
    loader: ‘babel’
  }, {
    test: /\.scss$/,
    exclude: path.resolve(__dirname, ‘src/styles’),
    loader: ‘style!css?modules&localIdentName=[name]__[local]!sass?sourceMap=true’
  }, {
    test: /\.scss$/,
    include: path.resolve(__dirname, ‘src/styles’),
    loader: ‘style!css!sass?sourceMap=true’
  }]
}

JavaScript

/* src/app.js */ import ‘./styles/app.scss’; import Component from
‘./view/Component’ /* src/views/Component.js */ // 以下为组件相关样式
import ‘./Component.scss’;

1
2
3
4
5
6
7
/* src/app.js */
import ‘./styles/app.scss’;
import Component from ‘./view/Component’
 
/* src/views/Component.js */
// 以下为组件相关样式
import ‘./Component.scss’;

目录结构如下:

JavaScript

src ├── app.js ├── styles │ ├── app.scss │ └── normalize.scss └── views
├── Component.js └── Component.scss

1
2
3
4
5
6
7
8
src
├── app.js
├── styles
│   ├── app.scss
│   └── normalize.scss
└── views
    ├── Component.js
    └── Component.scss

这么具有全局的样式都放到 src/styles/app.scss
中引入就可以了。其余具有目录包蕴 src/views 中的样式都是部分的。

四、 Class 的组合

在 CSS Modules
中,一个选拔器能够继续另一个选拔器的平整,那称之为”组合”(“composition”)。

在App.css中,让.title继承.className

JavaScript

.className { background-color: blue; } .title { composes: className;
color: red; }

1
2
3
4
5
6
7
8
.className {
  background-color: blue;
}
 
.title {
  composes: className;
  color: red;
}

App.js不用修改。

JavaScript

import React from ‘react’; import style from ‘./App.css’; export default
() => { return ( <h1 className={style.title}> Hello World
</h1> ); };

1
2
3
4
5
6
7
8
9
10
import React from ‘react’;
import style from ‘./App.css’;
 
export default () => {
  return (
    <h1 className={style.title}>
      Hello World
    </h1>
  );
};

运行那几个示例。

JavaScript

$ npm run demo04

1
$ npm run demo04

打开

App.css编译成上面的代码。

JavaScript

._2DHwuiHWMnKTOYG45T0x34 { color: red; } ._10B-buq6_BEOTOl9urIjf8 {
background-color: blue; }

1
2
3
4
5
6
7
._2DHwuiHWMnKTOYG45T0x34 {
  color: red;
}
 
._10B-buq6_BEOTOl9urIjf8 {
  background-color: blue;
}

对应地, h1的class也会编译成<h1 class=”_2DHwuiHWMnKTOYG45T0x34
_10B-buq6_BEOTOl9urIjf8″>。

JS CSS不可能共享变量

复杂组件要采用 JS 和 CSS 来共同处理体制,就会导致有些变量在 JS 和 CSS
中冗余,CSS预处理器/后处理器 等都不提供跨 JS 和 CSS 共享变量那种能力。

总结

CSS Modules 很好的化解了 CSS 如今边临的模块化难点。帮助与
Sass/Less/PostCSS
等搭配使用,能充裕利用现有技术积淀。同时也能和全局样式灵活搭配,便于项目中国和日本渐搬迁至
CSS Modules。CSS Modules
的落实也属轻量级,将来有专业解决方案后可以低本钱迁移。若是您的出品中恰恰赶上类似题材,卓殊值得一试。

1 赞 2 收藏
评论

亚洲必赢官网 7

五、输入任何模块

选取器也得以持续其余CSS文件之中的条条框框。

another.css

JavaScript

.className { background-color: blue; }

1
2
3
.className {
  background-color: blue;
}

App.css可以继承another.css里面的平整。

JavaScript

.title { composes: className from ‘./another.css’; color: red; }

1
2
3
4
.title {
  composes: className from ‘./another.css’;
  color: red;
}

运作那几个示例。

JavaScript

$ npm run demo05

1
$ npm run demo05

打开

年富力强并且扩充方便的CSS

作为有追求的工程师,编写健壮并且扩展方便的CSS一直是大家的对象。那么哪些定义健壮并且伸张方便?有五个大旨:

  • 面向组件 – 处理 UI 复杂性的最佳实践就是将 UI 分割成一个个的小组件
    Locality_of_reference
    。如果你正在使用一个理所当然的框架,JavaScript
    方面就将原生辅助(组件化)。举个例子,React
    就鼓励高度组件化和细分。大家希望有一个 CSS 架构去匹配。
  • 沙箱化(Sandboxed) –
    若是一个零部件的体制会对其余零件发生不需要以及意外的影响,那么将
    UI
    分割成组件并不曾什么用。就那上面而言,CSS的全局意义域会给你造成负担。
  • 便利 –
    大家想要所有好的东西,并且不想暴发越多的行事。也就是说,大家不想因为运用那个架构而让我们的开发者体验变得更糟。可能的话,大家想开发者体验变得更好。

六、输入变量

CSS Modules 援救接纳变量,然而要求设置 PostCSS 和
postcss-modules-values。

JavaScript

$ npm install –save postcss-loader postcss-modules-values

1
$ npm install –save postcss-loader postcss-modules-values

把postcss-loader加入webpack.config.js。

JavaScript

var values = require(‘postcss-modules-values’); module.exports = {
entry: __dirname + ‘/index.js’, output: { publicPath: ‘/’, filename:
‘./bundle.js’ }, module: { loaders: [ { test: /.jsx?$/, exclude:
/node_modules/, loader: ‘babel’, query: { presets: [‘es2015’,
‘stage-0’, ‘react’] } }, { test: /.css$/, loader:
“style-loader!css-loader?modules!postcss-loader” }, ] }, postcss: [
values ] };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var values = require(‘postcss-modules-values’);
 
module.exports = {
  entry: __dirname + ‘/index.js’,
  output: {
    publicPath: ‘/’,
    filename: ‘./bundle.js’
  },
  module: {
    loaders: [
      {
        test: /.jsx?$/,
        exclude: /node_modules/,
        loader: ‘babel’,
        query: {
          presets: [‘es2015’, ‘stage-0’, ‘react’]
        }
      },
      {
        test: /.css$/,
        loader: "style-loader!css-loader?modules!postcss-loader"
      },
    ]
  },
  postcss: [
    values
  ]
};

接着,在colors.css其间定义变量。

JavaScript

@value blue: #0c77f8; @value red: #ff0000; @value green: #aaf200;

1
2
3
@value blue: #0c77f8;
@value red: #ff0000;
@value green: #aaf200;

App.css可以引用这么些变量。

JavaScript

@value colors: “./colors.css”; @value blue, red, green from colors;
.title { color: red; background-color: blue; }

1
2
3
4
5
6
7
@value colors: "./colors.css";
@value blue, red, green from colors;
 
.title {
  color: red;
  background-color: blue;
}

运作这一个示例。

JavaScript

$ npm run demo06

1
$ npm run demo06

打开

1 赞 3 收藏
评论

亚洲必赢官网 8

CSS模块化方案分类

CSS 模块化的解决方案有好多,但重点有三类。

CSS 命名约定

规范化CSS的模块化解决方案(比如BEM BEM — Block Element
Modifier,OOCSS,AMCSS,SMACSS,SUITCSS)
但存在以下难点:
* JS CSS之间依旧没有打通变量和选用器等
* 复杂的命名

CSS in JS

根本废弃 CSS,用 JavaScript 写 CSS 规则,并内联样式。 React: CSS in JS
// Speaker
Deck。Radium,react-style
属于这一类。但存在以下难点:
* 不可能利用伪类,媒体询问等
* 样式代码也会出现大批量再次。
* 不可能利用成熟的 CSS 预处理器(或后电脑)

拔取JS 来保管体制模块

动用JS编译原生的CSS文件,使其负有模块化的力量,代表是 CSS Modules
GitHub – css-modules/css-modules: Documentation about
css-modules 。

CSS Modules 能最大化地组成现有 CSS 生态(预处理器/后电脑等)和 JS
模块化能力,大概零学学费用。只要您使用
Webpack,可以在其余项目中动用。是小编以为当前最好的 CSS 模块化解决方案。

CSS Modules 使用教程

启用 CSS Modules

JavaScript

// webpack.config.js
css?modules&localIdentName=[name]__[local]-[hash:base64:5]

1
2
// webpack.config.js
css?modules&localIdentName=[name]__[local]-[hash:base64:5]

加上 modules 即为启用,localIdentName 是安装生成样式的命名规则。

CSS

/* components/Button.css */ .normal { /* normal 相关的具备样式 */ }

1
2
/* components/Button.css */
.normal { /* normal 相关的所有样式 */ }

JavaScript

// components/Button.js import styles from ‘./Button.css’;
console.log(styles); buttonElem.outerHTML = `<button
class=${styles.normal}>Submit</button>`

1
2
3
4
// components/Button.js
import styles from ‘./Button.css’;
console.log(styles);
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

生成的 HTML 是

XHTML

<button class=”button–normal-abc53″>Submit</button>

1
<button class="button–normal-abc53">Submit</button>

注意到 button--normal-abc53 是 CSS Modules 按照 localIdentName
自动生成的 class 名。其中的abc53
是按照给定算法生成的系列码。经过那样模糊处理后,class
名基本就是绝无仅有的,大大下跌了连串中样式覆盖的几率。同时在生养环境下修改规则,生成更短的
class 名,可以增长 CSS 的压缩率。

上例中 console 打印的结果是:

CSS

Object {   normal: ‘button–normal-abc53’,   disabled:
‘button–disabled-def886’, }

1
2
3
4
Object {
  normal: ‘button–normal-abc53’,
  disabled: ‘button–disabled-def886’,
}

CSS Modules 对 CSS 中的 class 名都做了处理,使用对象来保存原 class
和模糊后 class 的对应关系。

通过那么些概括的处理,CSS Modules 完结了以下几点:
* 所有样式都是一对效用域 的,解决了全局污染难点
* class 名生成规则配置灵活,可以此来压缩 class 名
* 只需引用组件的 JS 就能搞定组件所有的 JS 和 CSS
* 如故是 CSS,大概 0 学习开销

CSS Modules 在React中的实践

那么我们在React中怎么利用?

手动引用解决

className 处直接利用 css 中 class 名即可。

JavaScript

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>
        </div>;     } }

1
2
3
4
5
6
7
8
9
10
11
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>
        </div>;
    }
}

渲染出来的零件出来

XHTML

<div class=”table__table___32osj”>     <div
class=”table__row___2w27N”>     </div> </div>

1
2
3
4
<div class="table__table___32osj">
    <div class="table__row___2w27N">
    </div>
</div>

react-css-modules

尽管你不想频仍的输入 styles.**,有一个 GitHub –
gajus/react-css-modules: Seamless mapping of class names to CSS modules
inside of React
components.,它通过高阶函数的花样来扭转className,然则不引进应用,后文仲提到。

API也很粗略,给组件外包一个CSSModules即可。

JavaScript

import React from ‘react’; import CSSModules from ‘react-css-modules’;
import styles from ‘./table.css’;   class Table extends React.Component
{     render () {         return <div styleName=’table’>
        </div>;     } }   export default CSSModules(Table,
styles);

1
2
3
4
5
6
7
8
9
10
11
12
import React from ‘react’;
import CSSModules from ‘react-css-modules’;
import styles from ‘./table.css’;
 
class Table extends React.Component {
    render () {
        return <div styleName=’table’>
        </div>;
    }
}
 
export default CSSModules(Table, styles);

然则那样咱们得以看来,它是索要周转时的依赖,而且须要在运作时才拿走className,质量损耗大,那么有没有便宜又似乎无损的措施吗?答案是有些,使用babel插件babel-plugin-react-css-modulesGitHub
– gajus/babel-plugin-react-css-modules: Transforms styleName to
className using compile time CSS module
resolution.亚洲必赢官网
className赢得前置到编译阶段。

babel-plugin-react-css-modules

babel-plugin-react-css-modules
可以兑现选择styleName属性自动加载CSS模块。大家通过该babel插件来进展语法树解析并最生平成className

来看看组件的写法,现在您只需要把className换成styleName即可获得CSS局地功能域的能力了,是或不是相当简单。

JavaScript

import React from ‘react’; import styles from ‘./table.css’;   class
Table extends React.Component {     render () {         return <div
styleName=’table’>         </div>;     } }   export default
Table;

1
2
3
4
5
6
7
8
9
10
11
import React from ‘react’;
import styles from ‘./table.css’;
 
class Table extends React.Component {
    render () {
        return <div styleName=’table’>
        </div>;
    }
}
 
export default Table;

干活规律

那就是说该babel插件是怎么工作的吧?让大家从官方文档出手:

GitHub – gajus/babel-plugin-react-css-modules: Transforms styleName to
className using compile time CSS module
resolution.

作者不才 ,稍作翻译如下:
1.
创设每个文件的兼具样式表导入的目录(导入具有.css.scss伸张名的文本)。

  1. 使用postcss
    解析匹配到的css文件
  2. 遍历所有
    JSX
    元素注明
  3. styleName 属性解析成匿名和命名的片段css模块引用
  4. 摸索与CSS模块引用相匹配的CSS类名称:
    * 如果styleName的值是一个字符串字面值,生成一个字符串字面值。
    *
    若是是JSXExpressionContainer,在运行时行使helper函数来创设如若styleName的值是一个jSXExpressionContainer,
    使用扶助函数([getClassName]在运转时社团className值。
  5. 从要素上移除styleName属性。
    7.
    将转变的className加上到存活的className值中(倘诺不设有则成立className属性)。

应用实例

在成熟的系列中,一般都会用到CSS预处理器或者后电脑。

那里以应用了stylusCSS预处理器为例子,我们来看下怎么样行使。

  • 设置信赖

Shell

npm install -save-dev sugerss babel-plugin-react-css-modules

1
npm install -save-dev sugerss babel-plugin-react-css-modules
  • 编写Webpack配置
JavaScript

// webpack.config.js module: {   loaders: \[{     test: /\\.js?$/,
    loader: \[\['babel-plugin-react-css-modules',{
          generateScopedName:'\[name\]\_\_\[local\]',
          filetypes: {               ".styl": "sugerss"            }
     }\]\]   }, {     test: /\\.module.styl$/,     loader:
'style!css?modules&localIdentName=\[name\]\_\_\[local\]!styl?sourceMap=true'
  }, {     test: /\\.styl$/,     loader:
'style!css!styl?sourceMap=true'   }\] }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-13">
13
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-14">
14
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-15">
15
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-16">
16
</div>
<div class="crayon-num" data-line="crayon-5b8f6729d9ed4116610999-17">
17
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6729d9ed4116610999-18">
18
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6729d9ed4116610999-1" class="crayon-line">
// webpack.config.js
</div>
<div id="crayon-5b8f6729d9ed4116610999-2" class="crayon-line crayon-striped-line">
module: {
</div>
<div id="crayon-5b8f6729d9ed4116610999-3" class="crayon-line">
  loaders: [{
</div>
<div id="crayon-5b8f6729d9ed4116610999-4" class="crayon-line crayon-striped-line">
    test: /\.js?$/,
</div>
<div id="crayon-5b8f6729d9ed4116610999-5" class="crayon-line">
    loader: [['babel-plugin-react-css-modules',{
</div>
<div id="crayon-5b8f6729d9ed4116610999-6" class="crayon-line crayon-striped-line">
          generateScopedName:'[name]__[local]',
</div>
<div id="crayon-5b8f6729d9ed4116610999-7" class="crayon-line">
          filetypes: {
</div>
<div id="crayon-5b8f6729d9ed4116610999-8" class="crayon-line crayon-striped-line">
              &quot;.styl&quot;: &quot;sugerss&quot;
</div>
<div id="crayon-5b8f6729d9ed4116610999-9" class="crayon-line">
           }
</div>
<div id="crayon-5b8f6729d9ed4116610999-10" class="crayon-line crayon-striped-line">
     }]]
</div>
<div id="crayon-5b8f6729d9ed4116610999-11" class="crayon-line">
  }, {
</div>
<div id="crayon-5b8f6729d9ed4116610999-12" class="crayon-line crayon-striped-line">
    test: /\.module.styl$/,
</div>
<div id="crayon-5b8f6729d9ed4116610999-13" class="crayon-line">
    loader: 'style!css?modules&amp;localIdentName=[name]__[local]!styl?sourceMap=true'
</div>
<div id="crayon-5b8f6729d9ed4116610999-14" class="crayon-line crayon-striped-line">
  }, {
</div>
<div id="crayon-5b8f6729d9ed4116610999-15" class="crayon-line">
    test: /\.styl$/,
</div>
<div id="crayon-5b8f6729d9ed4116610999-16" class="crayon-line crayon-striped-line">
    loader: 'style!css!styl?sourceMap=true'
</div>
<div id="crayon-5b8f6729d9ed4116610999-17" class="crayon-line">
  }]
</div>
<div id="crayon-5b8f6729d9ed4116610999-18" class="crayon-line crayon-striped-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>

  • 零件写法

JavaScript

import React from ‘react’; import ‘./table.module.styl’;   class Table
extends React.Component {     render () {         return <div
styleName=’table’>         </div>;     } }   export default
Table;

1
2
3
4
5
6
7
8
9
10
11
import React from ‘react’;
import ‘./table.module.styl’;
 
class Table extends React.Component {
    render () {
        return <div styleName=’table’>
        </div>;
    }
}
 
export default Table;

如上,你能够经过安顿Webpack中module.loaders的test路径Webpack-module-loaders-configuration,来分化样式文件是还是不是要求CSS模块化。
搭配sugerss这个postcss插件作为stylus的语法加载器,来支撑babel插件babel-plugin-react-css-modules的语法解析。

终极大家回过头来看下,我们React组件只须求把className换成styleName,搭配以上构建配置,即可兑现CSS模块化

最后

CSS Modules 很好的解决了 CSS 方今边临的模块化难点。帮衬与
CSS处理器搭配使用,能丰盛利用现有技术积淀。若是您的产品中正好遇见类似难点,分外值得一试。

期望大家都能写出健康并且可扩充的CSS,以上。

1 赞 2 收藏
评论

亚洲必赢官网 9

网站地图xml地图