CSS 工程化的目的是解决以下问题:
- 宏观设计:如何组织 CSS 代码、如何拆分、如何设计模块结构?
- 编码优化:如何编写更好的 CSS 代码?
- 构建:如何处理 CSS 代码,以让打包结果最佳?
- 可维护性:代码写完后,如何最小化后续变更的成本?如何确保任何同事都能轻松接手?
以下三个方向是当前比较流行且普适的 CSS 工程化实践:
- 预处理器:如 Less、Sass 等;
- 重要的工程化插件:PostCss;
- Webpack loader 等。
基于这三个方向,可以衍生出一些具有典型意义的子问题,以下我们逐个来看:
预处理器
为什么要用预处理器?它的出现是为了解决什么问题?
预处理器是 CSS 世界的“轮子”。它支持我们使用类似 CSS 但不同于 CSS 的语言,然后将其编译成 CSS 代码。
为什么要使用预处理器?因为传统 CSS 存在以下问题:
- 宏观设计上:我们希望优化 CSS 文件的目录结构,实现对现有 CSS 文件的复用;
- 编码优化上:我们希望编写结构清晰、简明易懂的 CSS 代码,需要它具有一目了然的嵌套层级关系,而不是无差别的一铺到底写法;我们希望它具有变量特征、计算能力、循环能力等更强的可编程性,这样我们可以少写一些无用的代码;
- 可维护性上:更强的可编程性意味着更优质的代码结构,实现复用意味着更简单的目录结构和更强的拓展能力。这两点如果实现,自然会带来更强的可维护性。
预处理器普遍具备以下特性:
- 嵌套代码能力,通过嵌套反映不同 CSS 属性之间的层级关系;
- 支持定义 CSS 变量;
- 提供计算函数;
- 允许对代码片段进行 extend 和 mixin;
- 支持循环语句的使用;
- 支持将 CSS 文件模块化,实现复用。
PostCss
PostCss 是如何工作的?我们在什么场景下会使用 PostCss?
PostCss 和预处理器的不同之处在于,预处理器处理的是类 CSS,而 PostCss 处理的是 CSS 本身。类似 Babel 可以将高版本的 JavaScript 代码转换为低版本的 JavaScript 代码。PostCss 做的是类似的事情:它可以编译尚未被浏览器广泛支持的先进 CSS 语法,还可以自动为一些需要额外兼容的语法增加前缀。由于 PostCss 有着强大的插件机制,支持各种各样的扩展,它极大地强化了 CSS 的能力。
PostCss 在业务中的使用场景非常多:
- 提高 CSS 代码的可读性:PostCss 可以做类似预处理器能做的工作;
- 当我们的 CSS 代码需要适配低版本浏览器时,PostCss 的 Autoprefixer 插件可以帮助我们自动增加浏览器前缀;
- 允许我们编写面向未来的 CSS:PostCss 能够帮助我们编译 CSS next 代码。
Webpack 能处理 CSS 吗?
在裸奔的 Webpack 中,是不支持直接处理 CSS 文件的。这时我们需要使用 loader 将 CSS 文件转换为 JS 对象,再交给 Webpack 去处理。
Webpack 提供了一些常用的 CSS loader,如 css-loader
、style-loader
等。其中 css-loader
可以将 CSS 文件转换为 JS 对象,而 style-loader
则可以将 JS 对象转换为样式标签,插入到 HTML 文件中。
除此之外,Webpack 还支持一些优秀的 CSS 工具,如 postcss-loader
、sass-loader
等,它们可以帮助我们在打包过程中自动编译 Sass 文件,自动为 CSS 添加浏览器前缀,自动压缩 CSS 文件等等。
总之,Webpack 在处理 CSS 方面,提供了非常丰富的 loader 和插件,让我们可以非常方便地进行 CSS 工程化的开发。