CSS 工程化
zKing 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')
]
}