工程化为了解决什么问题
宏观设计:CSS 代码如何组织、如何拆分、模块结构怎样设计编码优化:怎样写出更好的 CSS构建:如何处理我的 CSS,才能让它的打包结果最优可维护性:代码写完了,如何最小化它后续的变更成本?如何确保任何一个同事都能轻松接手?
预处理器
预处理器,其实就是 CSS 世界的"轮子"。大家如果是初识预处理器,你可以类比 JS 世界的 Vue、React来理解它。 预处理器支持我们写一种类似 CSS、但实际并不是 CSS 的语言,然后把它编译成 CSS 代码:
为什么写 CSS 代码写得好好的,偏偏要转去写"类 CSS"呢?这个道理就和我们本来用 JS 也可以一把梭实现所有功能,但最后却一窝蜂跑去写 React 的 jsx 或者 Vue 的模板语法是一样的——为了爽!
要想知道有了预处理器有多爽,我们首先要知道的是传统 CSS 有多不爽。随着前端业务复杂度的提高,前端工程中对 CSS 提出了以下的诉求:
宏观设计上:希望能优化 CSS 文件的目录结构,对现有的 CSS 文件实现复用;编码优化上:希望能写出结构清晰、简明易懂的 CSS,需要它具有一目了然的嵌套层级关系,而不是无差别的一铺到底写法;我们希望它具有变量特征、计算能力、循环能力等等更强的可编程性,这样我们可以少写一些无用的代码;可维护性上:更强的可编程性意味着更优质的代码结构,实现复用意味着更简单的目录结构和更强的拓展能力,这两点如果能做到,自然会带来更强的可维护性。
这三点是传统 CSS 所做不到的,也正是预处理器所解决掉的问题。预处理器五花八门,它们普遍会具备这样的特性:
- 嵌套代码的能力,通过嵌套来反映不同 css 属性之间的层级关系 ;
- 支持定义 css 变量;
- 提供计算函数;
- 允许对代码片段进行 extend 和 mixin;
- 支持循环语句的使用;
- 支持将 CSS 文件模块化,实现复用。
PostCss
PostCss 仍然是一个对 CSS 进行解析和处理的工具,它会对 CSS 做这样的事情:
它和预处理器的不同就在于,预处理器处理的是 类CSS,而 PostCss 处理的就是 CSS 本身。
理解 PostCss,我们可以类比 JS 世界里的 Babel。大家知道,Babel 可以将高版本的 JS 代码转换为低版本的 JS 代码。PostCss 做的是类似的事情:它可以编译尚未被浏览器广泛支持的先进的 CSS 语法,还可以自动为一些需要额外兼容的语法增加前缀。更强的是,由于 PostCss 有着强大的插件机制,支持各种各样的扩展,极大地强化了 CSS 的能力。
PostCss 在业务中的使用场景非常多,列举几个最高频的:
- 提高 CSS 代码的可读性:PostCss 其实可以做类似预处理器能做的工作;
- 当我们的 CSS 代码需要适配低版本浏览器时,PostCss 的 Autoprefixer 插件可以帮助我们自动增加浏览器前缀;
- 允许我们编写面向未来的 CSS:PostCss 能够帮助我们编译 CSS next 代码;
Webpack 能处理 CSS 吗?
Webpack 在裸奔的状态下,是不能处理 CSS 的,Webpack 本身是一个面向 JavaScript 且只能处理 JavaScript 代码的模块化打包工具;Webpack 在 loader 的辅助下,是可以处理 CSS 的。Webpack 中操作 CSS 需要使用的两个关键的 loader:css-loader 和 style-loader。前者的作用是导入 CSS 模块,对 CSS 代码进行编译处理;后者的作用是创建style标签,把 CSS 内容写入标签。