如何评价 css modules sass

酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
,seeing is believing
谢邀。之前写过两个关于 CSS Modules 的答案:和在这里就不再重复了。TL;DR 我认为 CSS Modules 是目前最好的(React)CSS 解决方案。
CSS Modules 的优点主要是:
缺乏 Dead Code Elimination 的好方法可能是需要改进的部分之一。另外如果 composes 太多,输入相对路径很麻烦,那不妨设置一些。
另外今天在飞机上听了一期 React Podcast [1],嘉宾是在 React Europe 做 inline-styles talk 的 Michael Chan。嘉宾们诚实的列出了 inline-styles 的很多问题(比如对 pseudo-class 的支持缺乏等等),也表示在实际项目中的应用还是比较克制的。我觉得 inline-styles、Radium 和 CSS Modules 都是非常棒的思路和探索;也许每一种方案都不是银弹,但都是值得研究和改进的。
CoffeeScript 现在一点都不酷了,但若没有它 ES6 可能也不会长成。这个圈子里没有什么,或者说语言和工具的实现很大程度上是由社区主导的。对我来说这是 UI Engineering 这个社区最有趣的地方。
,不折腾会死星人 //
作为 BEM 的受益者,看到这类工具的出现是很开心的
与其费神的告诉别人要遵守某种规则,以规避某种痛苦,到不如从工具层面就灭到这种痛苦。
和 React 搭配使用,不能再愉快了。
再有之后,对于不想在 ReactNative 里写 inline css 的开发者,也是有可以开脑洞的借鉴。
当然其他基于模版,也是一样,只是需要绕一下,注入 classMap 到 scope 中。
维护上,前缀是文件路径 sourcemap 都省去了。
当前版本, 暂不支持 pre-processor,
不过其背后足够强大的 PostCSS 也组成一套 processor 了,
比如和一起用着,感觉没太多需要 Stylus, SASS 或者 LESS 的地方了。
另,有个不方便的地方,当前 父 Component 的对 子 Component 的样式覆写好像无能的样子,( class 名是自动生成的,除非用 :global(.component) 暴露到全局去,或者也许我们不该这么思考 ? )
Webpack 用户现在已经可以试用了,
Browserify 用户还需要面对一些坑 ( CSS 的生成路径不存在的话将无法或者文件, 报错之后要歇菜 )
Node 环境也正常,,用做测试环境,
用做模版引擎都是可行的。
最近几天由于这篇,让大家对 CSS Modules 有了很高的热情。我们团队已经使用 CSS Modules几个月了,所以在这里谈谈我们的经验。
文章发布在[](),欢迎订阅
我们的项目是使用React.js 开发,所以我们在开始开发的时候,为了能让我们的组件能够在多个项目中复用,我们开始调研单文件组件的写法,这期间看了,等内容,最终选择的方案是使用 radium 来写 css。
CSS in JS 虽然有,但是问题很多,让我们很不爽:
骆驼式命名的写法很蛋疼
丢失了 css 得灵活性
不能使用 css 预处理器
不能使用 css 的生态工具,如
非常难以调试,在 devtool 中修改只能修改当前的组件实例
所以我们也一直在寻找更好的方案,直到我们看到了这篇文章,我们终于找到了一个完美的方案。
这篇文章利用webpack 的 Local scoped CSS 以及 自己写了一个 postcss 的插件[]完成了现在所谓的。
再后来该作者给 webpack 的 css-loader 提了 pr,将该功能合并到了 css-loader 中。
然后我们的组件结构就变成了这样
webpack 的配置
test: /.css$/,
loader: &style!css?module&localIdentName=[hash:base64:5]&-url&
如果想用 sass 只需再加个 sass-loader 就好了 :)
代码类似这样
import styles from './FooBar.css';
import React from 'react';
export default class Demo ponent {
render() {
&div className={styles.root}&
&p className={styles.text}&Another Local Scope!&/p&
谈谈这样写的好处
保留了很好的组件复用性
消除了全局命名的问题,在组件的 index.css 中可以随意起名字,不用担心命名冲突
和react 结合很好
很方便的按需加载
另外由于 react-native 嫌弃 webpack 速度太慢,而独立开发了打包工具。所以我开发了一个将 css文件 打包成 style 对象的工具[instyle]()
有问题欢迎讨论
,前端大傻X一个
偶没咋看这个
只要是老外发的
只能无条件叫好
政治正确在圈里最重要
偶认为是好的
引领方向的
虽然偶对写文儿人所在地(Glen Maddern is an independent Web Developer from Melbourne, Australia.)表示开心,这可能是受微博上@灵感之源 ()的影响颇深所致。
但这不影响偶的观点
& 相关主题:最近一直在学习React,看上去蛮简单的内容,其实学习曲线还是比较高的。
目前学到css绑定的问题,看到有一篇好的文章,就转过来了。
CSS 模块化的解决方案有很多,但主要有两类。一类是彻底抛弃 CSS,使用 JS 或 JSON 来写样式。Radium,&&,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 Modules 模块化方案
CSS Modules 内部通过ICSS 来解决样式导入和导出这两个问题。分别对应&:import&和&:export&两个新增的伪类
:import("path/to/dep.css") {
localAlias: keyFromD
exportedKey: exportedV
但直接使用这两个关键字编程太麻烦,实际项目中很少会直接使用它们,我们需要的是用 JS 来管理 CSS 的能力。结合 Webpack 的&css-loader&后,就可以在 CSS 中定义样式,在 JS 中导入
阅读(...) 评论()CSS Modules 两月使用总结 - 掘金
阅读 2105收藏 50原文链接:CSS Modules 是一种新的组件化编写 CSS 的工具 + 方法论,很多人可能还没有使用起来,作者用它两个月的开发经验,告诉我们这种新的方法如何即满足了高效开发,也使得 code 且易于管理。 —— 由
“Move fast and break things” is what they said.
are definitely moving fast. In only two months we have gone from
having nothing but a feature list and early designs to having two beautiful,
component-sharing, fully functional apps built and shipping to companies
such as AirBnB, Google and M&C Saatchi.
The Three Ilities
While moving fast feels great (and is, of course, great) it can
very easily (and more often than not) come back to haunt you if you do
not approach it correctly. The problem, of course, are the “Three Code
Ilities” - maintability, scalability and stability. These are all needed
to maintain efficiency and sanity in the long run allowing us developers
to do our jobs and develop features within a 0-friction environment.
When moving fast these can become seriously comprompised as we tend to
cut corners, make hacks and even have to make sacrifices to code quality
in some areas.
This is not because we are bad developers but because we are humans
with a job to do, deadlines to hit and dependants we want to satisfy.
Unless you are writing a throw-away application it is important to choose
the right corners to cut, isolate the hacks and, probably most importantly,
have good infrastructure. Making sure the tools we are working
with day-to-day is vital to allowing everyone to maintain their work velocity
over a prolonged period. Facebook realised this and
(the now much less catchy) “Move fast with good infra”.
I could spend an age discussing strategies on how to develop quickly and
maintain the “three code ilities” but today I just want to focus on infrastructure
and on one piece in particular...
The Elephant
Take the hacks and cut corners away while moving fast, you will find CSS
is still a nightmare to work on as applications scale. I won’t repeat
what has been said a million times before so let’s just remind ourselves
of that one slide from that .
CSS was an Elephant and I’m glad we’ve addressed it.
At first CSS is lovely. And it's incredibly sastisfying how quick and
easy you can write your first styles and make some really good looking
components. If you’ve been developing on the web for a while I bet you
can still remember the first time you used CSS to render rounded corners...
However...
Over time we just keep adding and adding things to the codebase. All in
one namespace. This is like scaling vertically over horizontally which
works but only upto a point.
The visual states get more complex and more and more people get their
hands on it - it just begins to spiral and becomes that area nobody wants
“As most companies grow, they slow down too much because they’re more
afraid of making mistakes than they are of losing opportunities by moving
too slowly.” - Mark Zuckerberg
On large codebases I was certainly afraid of touching the CSS and I was
beyond fed up of writing verbose BEM class names to tip-toe around the
fundamental problem of CSS.
Enter CSS Modules
To remedy these problems and allow us to move at an electric pace we took
the early decision to implement and use the rather new and shiny CSS Modules
The fundamental of CSS Modules is simply having localised classes over
all classes being shared in a global namespace. Ie. If two components use
the class name .active their rules will not clash. This seems
like a very trivial thing but it makes us think about our styles in new
ways which I hope to demonstrate.
If you, for some reason, haven’t heard of or just not had time to read
up on CSS Modules yet I strongly recommend you go and read the
Glen Maddern (one of the original creators) to understand it’s core principles
and the problems it specifically sets out to solve.
Since it was very early days for the pattern it could be seen as a bit
of a punt to implement it as the fundamental ground work into what is going
to become a large enterprise platform but after two months...
I can now confirm CSS Modules has been a huge success and we are finally enjoying
loving CSS
Below I will try to document our experience with CSS Modules. The areas
it has helped improve and the decisions we have had to make to get us writing
styles without a worry in the world.
Disclaimer: The team has consisted of 4 developers working on 2 applications spanning hundreds of components working with CSS Modules every day for 2 months.
If you’re using webpack and React, like we are, you can literally start
using CSS Modules in the time it takes you to install the loader and import
a stylesheet.
If you haven’t seen already then once you are setup you will be able to
import your styles as object literals where the key are the class names
you defined in your CSS file.
// styles.css
.content {
padding: 5
// component.js
import styles from './styles.css'
render() {
&div className={styles.content}&Hello World!&/div&
If you are already using React or some other JS templating solution there
is pretty much no syntax (or other) overhead to direct referencing your
styles this way and in our experience having the explicit import and use
has made writing and maintaining drastically quicker.
You are following explicit directions to your source rather than seeing
an implicit class name and having to mentally figure out where it might be.
The explicit usage shows you it is right here!
Since getting installed 2 months ago we haven’t had to fiddle with the
configuration at all with the ine exception to optimize the outputted class
names during development for easy debugging. For this we arrived at localIdentName=[name]__[local]___[hash:base64:5] which
lets us quickly see which component and class name we are working with
and maintains uniqueness with the hash (although we should never actually
have clashing component names!).
“Everything is a Component”
When writing CSS as localized modules you will really need to get into
the mindset of thinking of everything as small individual components. If
you’ve been developing with React or even using BEM the chances are you’re
already working with this mindset and so the transition to forcing components
into a localized state should be trivial.
Having these localized components provides a huge mental win now
that we no longer have to even think about other components. We can focus
purely on the component in front of us which helps us focus and work much
more efficiently. We go back to having a small isolated piece of code we
can work on free from outside restrictions. Thinking of each component
as a mini app we go back to the scale at which CSS was fun again!
This is the difference between writing a stateless function or a mutable
class (which I explore more later).
The biggest leap we at
was getting over the inability to target a child component from within
a containing component. For example you couldn’t expect to do something
like this:
// Override child component styles from parent component
// Where our `button` and `buttonGroup` are *supposed* to
// be separate components
.buttonGroup .button {
padding: 5
Now, this is somewhat of an anti-pattern in itself as it took away from
the encapsulation of individual components which just do their thing but
the ease of targeting selectors in CSS meant we could target these specific
compositions easily and override styles from a parent component.
Instead of doing this we should instead be moving this customization of
the child to the child’s API itself. Ie. In the above example the child
component would expose a modifier. Eg. padded which we could
then use when initializing our component.
I’ve included a React example below to see how this actually works.
&ButtonGroup&
&Button padded={true} /&
&/ButtonGroup&
// or ButtonGroup can be made to pass the `padded`
// prop implicitly by mapping it’s children
Style Purity
Component encapsulation lets us develop CSS with the wind in our hair
and peace-of-mind. I’m no longer wasting time thinking about how to avoid
name clashes, worrying about specificity issues or having nightmares over
how changing that one selector might break my styles but I’m just concerned
with how my component looks and how the public interface appears.
This encapsulation and forced component scope ensures we can develop our
styles in complete isolation and therefore making our styles pure.
From functional programming we have learned of the great benefits surrounding
purity and lack of side-effects so having this insurance on our component
styles is a huge win for testability and peace-of-mind when developing.
I am no longer writing a mutable class. I am writing a function!
Now that I have my pure function it is incredibly easy to whip out a few
test fixtures for my component et voila, sanity (and no nightmares).
Customization
As discussed in the “everything is a component” section we have seen that
we lose the ability to target children and override styles which limits
the level of customization we can achieve directly from our CSS file.
Customization therefore becomes a case of either expanding your component
API or creating new components which compose your base components. So far
we have found no concrete rule on when to choose one pattern over the other
but have preferred to simply expand a component’s API before creating a
new component as at least in the mid term we will not have to go looking
in too many different places.
On that note - when moving fast and expecting to maintain a codebase for
a long time in the future it is easier to keep functionality in one place
which can be later extracted than it is to do the reverse. That as well
as you never want code to be too fragmented before you need it (we,
as developers, often have a tendancy to over-abstract too early rather
than build things and watch the patterns emerge themselves to easily see
the most effective abstraction).
Tip: As a good example of composability, ease-of-use and familiarity we
have created H1, H2 and H3 components
which all simply compose the base Heading component.
Style Normalization
You will still want your normalize.css stylesheet to sit at
the top of your application’s component hierarchy, that is for sure.
In our experience we have found this is the only stylesheet which
will ever target tags globally. You can create localised components for everything -
even for all our typography we have created Text and Heading components
for re-use which has not shown any downsides thus far.
Composition and DRY
The CSS Modules spec supports a composes keyword which gives
you sort of extend-like functionality.
composes: .default from &typography.css&;
While I can imagine this is helpful for non-React developers we have found
it basically redundant in our React application as we can already very
easily compose our React components and therefore there is no need for
composing the underlying styles. (Note if anyone has found any applicable uses for this in React please give me a shout and I can update this!)
Currently you will also need to implement some way to share your common
variables to avoid hard-coding any values in your CSS rules. I'd advise
plugin for
this (there's a load so you can choose one to fit your team's preference!).
There are discussions at the moment however revolving around bringing a
into CSS Modules which are shaping up rather nicely!
On the subject of keeping code DRY I would like to highlight the fantastic talk (just 25 mins) by Sebastian Markbage on
which has inspired our approach to moving quickly in a maintainable fashion greatly. The premise of this being not to over-abstract too early and create too many fragmented pieces within your stack.
Interopable component styles at scale
A component’s styles should only be concerned with styling that component
and not have any side-effects on sibling components. Right? It seems strange
then that we add a property such as margin to our styles which
have the side effect of shifting components.
Why should our .heading component be pushing sibling components
away? What happens we have two .button components together and
we need spacing? What happens when we have a .button component
proceeding an .input component and want spacing?
Traditionally we had the power to go in and work with side-effect selectors
such as .button + .input or .heading + .paragraph which
would target certain sequences of components. This, combined with us usually
putting default spacing around all kinds of components, meant we had side-effects
everywhere and meant our component styles were no longer responsible for just one thing
but when using them we had to account for how they would affect other components.
This works for a while but then grows out of control as you re-use components
everywhere and want unique control over layout and spacing in various containers.
In our opinion for the best, CSS Modules removes the ability to do this
kind of targeting due to the local scope.
We still haven’t found the perfect solution but we have started working
on a few things.
Firstly no component should ever emit any spacing side-effect style
such as a margin by default. We can instead (if appropiate)
expose a generic, well-defined & explicit API for control of such styles
at the component initialization time (this is when you know all about surrounding
components and can lay out accordingly).
Provide generic layout components which wrap children with an extra component
of which it’s sole purpose is to position it’s children accordingly. For
example we have a List component which wraps all children with
a ListItem component which solely emits spacing (margin)
styles. There is a well-defined API to control the styles which has the
added benefit of providing consistency across our app.
Would really love to hear some opinions, ideas & thoughts around this stuff in particular!
With typical global CSS naming is super important. If you don’t
choose a good standard early on or even begin to deviate slightly somewhere
(it happens when you’re up against the wall and moving quickly - that’s
reality!) then you will quickly lose control.
Obviously, with CSS Modules, there is less of an emphasis on getting naming perfect as
names are only local to the component you are developing. This said you
still shouldn’t be having multiple developers going off doing their own
thing all at once as consistency is helpful for maintainability and getting
new developers onboarded and working quickly.
we’ve approached this as we
have everything else with a “minimum standard, get stuff done and watch
patterns emerge” approach.
The idea there is that you:
Construct a minimum standard which prevents any wild deviations - and
being minimal it is quick and doesn’t restrict too much creative thinking
Get developing and ensure open code reviews - which prevents people doing
anything crazy and allows for transparency and discussion to occur
Watch and you will see the good patterns emerge and live and the bad patterns
die as developers try slightly different things.
CSS Modules Quick Tips
A few final quick tips:
Keep CSS files next to the relevant component/template for easy navigation.
Every component in our codebase is a self-contained directory
containing the component [button.jsx], component styles [button.css], tests
[button-test.jsx] and an index [index.js] for less verbose imports.
If using React and classnames dependency implement an .undefined !important class
during development which will catch any mis-used style names.
Conclusion
In short I have loved CSS Modules and how it is encouraging me to write
my styles. We spend less time fixing bugs, write styles more quickly and
just generally feel better about our codebase which is massively important!
The biggest win from using CSS Modules is not simply having localised
CSS files but the patterns it encourages us to use.
I have likened it to my experience with React which has, quite simply,
transformed how I think about and develop UI’s.
All in all CSS Modules has provided us with a sane piece of infrastructure
around styling which will allow us to move forward without any deacceleration
of development in the long-term.
In terms of the three ilities:
Maintability - Strong component encapsulation means it
is easy to locate where to make changes and doesn’t require external contextual
Scalability - Pure component and style architecture means
infinite developers can work on infinite components atomically.
Stability - Pure styles makes testing easy and breaking
things difficult.
Just published "Elephants, The Three Code Ilities and 2 months with CSS
— Chris Pearce (@Chrisui)
Feel free to follow and give me a shout on Twitter
for whatever reason! :)
相关热门文章

我要回帖

更多关于 css modules 的文章

 

随机推荐