CSS 工程化


2019-01-09 CSS

摘要

所谓的工程化,包含四个方面

  • 组织
  • 优化
  • 构建
  • 维护

在 CSS 工程中,使用 CSS 预处理器来组织代码,使用 PostCSS + Webpack/Gulp 等工具来优化、构建、维护代码。

# CSS 预处理器

预处理器是基于 css 所扩展出来的新的语言,目前常用的有三种:Less,Sass,Stylus

# 预处理器的作用

  • 帮助更好地组织css代码
  • 提高代码复用率
  • 提升可维护性

# 预处理器的能力

  • 嵌套
  • 变量和计算
  • extend 和 mixmin
  • 循环
  • import 模块化

# Stylus

三种预处理器各有各的好处,但我个人偏爱使用 stylus,以下是简单的示例,更多请点击这里

$font-size = 28px
$bg-black = #020200

$vendor(prop, args)
  -webkit-{prop}: args
  -moz-{prop}: args
  {prop}: args

$border-radius(arguments)
  $vendor(border-radius, arguments)

/* ===================================== */

body
  font: ($font-size / 2)

a.button
  $border-radius(5px)

p
  background-color: $bg-black

.box
  background-color: $bg-black
  width: $w = 200px
  height: $w
  margin-left: ($w / 2)
  $border-radius(10px)

# 关于 PostCSS

PostCSS 其实可以算是 CSS 后处理器,但其实现在其强大到可以都代替预处理器了,更多可以点击 这里

# 常见的插件

PostCSS本身只有解析能力,各种神奇的特性全靠插件,目前至少有200多个插件,常见的插件有以下几个

  • postcss-import 模块合并
  • autoprefixier 自动加前缀
  • postcss-cssnano 压缩代码
  • postcss-cssnext 使用 css 新特性
  • precss 变量、mixin,循环之类的特性
  • postcss-calc 在编译阶段进行计算,减少不必要的 calc ,而开发时用 calc 更清晰。
  • postcss-plugin-px2rem 将px转成rem,适配各种屏幕。
  • postcss-modules 用来解决 css 命名冲突问题

# 使用示例

这是使用 Webpack4 + PostCSS + Stylus 搭成的例子

package.json,这是我使用的版本

"dependencies": {
  "stylus": "^0.54.5",
  "webpack": "^4.25.1"
},
"devDependencies": {
  "autoprefixer": "^9.4.4",
  "css-loader": "^0.28.11",
  "html-webpack-plugin": "^3.2.0",
  "mini-css-extract-plugin": "^0.5.0",
  "postcss": "^7.0.8",
  "postcss-calc": "^7.0.1",
  "postcss-import": "^12.0.1",
  "postcss-loader": "^3.0.0",
  "postcss-modules": "^1.4.1",
  "postcss-plugin-px2rem": "^0.8.1",
  "precss": "^4.0.0",
  "stylus-loader": "^3.0.2",
  "webpack-cli": "^3.1.2"
}
  • 使用 mini-css-extract-plugin 会和 style-loader 冲突,所以不用 style-loader
  • css-loader 1.0.0 以后没有 minimize 选项了,所以使用 0.28.11 的版本

webpack.config.js

const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  mode: 'development',
  context: path.resolve(__dirname, './src'),
  entry: {
    app: './app.js'
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [{
      test: /\.css$/,
      use: [
         MiniCssExtractPlugin.loader,
        {
          loader: 'css-loader',
          options: {
            minimize: true  // 这里直接用minimize来进行压缩,而不使用postcss的cssnano插件
          }
        },
        'postcss-loader'
      ]
    }, {
      test: /\.styl$/,
      use: [
         MiniCssExtractPlugin.loader,
        {
          loader: 'css-loader',
          options: {
            minimize: true
          }
        },
        'postcss-loader',
        'stylus-loader'
      ]
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './index.html' }),
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css"
    })
  ],
  devtool: 'source-map'
}

postcss.config.js


module.exports = {
  plugins: [
    require('autoprefixer')({
      browsers: ['ie>=8', '>1% in CN']
    }),
    // require('cssnano'), 使用 css loader 的 minimize 来做压缩,就不用 cssnano 了
    // require('postcss-cssnext'), 安装 postcss-cssnext 需要很多依赖项,就不做示例了
    require('postcss-import'),
    require('postcss-calc'),
    require('postcss-plugin-px2rem'),
    require('precss'),
    require('postcss-modules')
  ]
}
最近更新: 12/22/2021, 3:23:15 PM