什么是css工程化,这个应该是目前前端的一个热点方向,如果在日趋复杂的项目更合理的维护和迭代,这个问题个人尤为重要,下面将展开目前我所认知的常规方案
PostCss
什么是postcss,有人说它是后处理器,个人觉得其实它跟前处理器(预处理器)背后所做的现在已经没差。官网的解释是:PostCSS 是一个允许使用 JS 插件转换样式的工具。 这些插件可以检查(lint)你的 CSS,支持 CSS Variables 和 Mixins, 编译尚未被浏览器广泛支持的先进的 CSS 语法,内联图片,以及其它很多优秀的功能
简单来说,postcss它只具备解析能力,至于转换能力就需要依赖插件(200+)
处理过程:
Css –> PostCss(模块化,加前缀,兼容性,css语法检查) –> Css
postcss-import
用于css文件的合并
1 2 3 4 5
| @import "./02-plugins-module.css"; .box{ box-shadow: 0 0 3px rgba(255,255,255, .3); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| /* css-reset */ *{ padding:0; margin:0; } body{ margin: 10px 20px 10px 20px; font-size:14px; } body{ background-color: }
|
1 2 3 4 5 6
| const atImport = require('postcss-import') module.exports = { plugins: [ atImport ] };
|
执行合并操作
1
| ./node_modules/.bin/postcss src/02-plugins-main.css -o build/02-plugins-main.css
|
autoprefixier
用于适配不同浏览器,自动加前缀
1 2 3 4 5 6 7 8
| const autoprefixer = require('autoprefixer') module.exports = { plugins: [ autoprefixer({ browsers:['last 2 verisons'] //指定最近两个版本 }) ] };
|
1
| ./node_modules/.bin/postcss src/02-plugins-main.css -o build/02-plugins-main.css
|
cssnano
用于资源压缩
1 2 3 4 5 6
| const cssnano = require('cssnano'); module.exports = { plugins: [ cssnano ] };
|
1
| ./node_modules/.bin/postcss src/02-plugins-main.css -o build/02-plugins-main.css
|
cssnext
用于解析css新特性(已定稿,但浏览器未实现)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| :root { --mainColor: red; --danger-theme: { color: white; background-color: red; }; } a { color: var(--mainColor); } .danger { @apply --danger-theme; }
|
1 2 3 4 5 6
| const cssnext = require('postcss-cssnext'); module.exports = { plugins: [ cssnext, ] };
|
1
| ./node_modules/.bin/postcss src/03.cssnext.css -o build/03.cssnext.css
|
结果:
1 2 3 4 5 6 7 8
| a { color: red; } .danger { color: white; background-color: red; }
|
precss
它类似于sass,能够解析变量,条件if,循环,mixin,import,属性引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| $blue: $column: 200px; .menu { width: calc(4 * $column); } .menu_link { background: $blue; width: $column; } .notice--clear { @if 3 < 5 { background: green; } @else { background: blue; } } @for $i from 1 to 3 { .b-$i { width: $(i)px; } }
|
1 2 3 4 5 6
| const precss = require('precss'); module.exports = { plugins: [ precss ] };
|
执行解析操作
1
| ./node_modules/.bin/postcss src/04.precss.css -o build/04.precss.css
|
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| .menu { width: calc(4 * 200px); } .menu_link { background: width: 200px; } .notice--clear { background: green } .b-1 { width: 1px; } .b-2 { width: 2px; } .b-3 { width: 3px; }
|
此外,PostCss它还可以跟其他构建工具集成使用,除了自己的PostCss-Cli,还可以跟Gulp,Webpack,Grunt,Rollup等等
gulp-postcss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const gulp = require('gulp'); const autoprefixer = require('autoprefixer'); const cssnano = require('cssnano'); const atImport = require('postcss-import'); gulp.task('postcss', function () { var postcss = require('gulp-postcss'); return gulp.src('src/02-plugins-main.css') .pipe(postcss([ atImport, autoprefixer({ browsers:['last 2 versions'] }), cssnano ])) .pipe(gulp.dest('build/')); });
|
webpack
在webpack中,js是整个应用的核心入口,也就是说css最终会被转为js,并且插入到dom中去
- 创建webpack.module.js,并暴露出去
1 2 3 4 5
| module.exports = { say: function(){ console.log('hello from module'); } }
|
- 创建webpack.main.js,引入webpack.module.js
1 2 3
| var module = require('./webpack-module.js'); module.say();
|
1
| ./node_modules/.bin/webpack src/webpack.main.js build/webpack.main.js
|
1 2
| ... <script src="build/webpack-main.js"></script>
|
直接require一个js文件没问题,如果我们在js直接require一个css文件的话,它是会报错,因为我们需要给它指定对应loader去处理css
1 2 3 4 5 6 7 8 9 10 11
| module.exports = { module: { rules: [ { test: /.\css$/, use: ['style-loader','css-loader'] } ] } }
|
首先css-loader负责会把css文件转为js文件交给webpack处理,再style.loader把变成js的css文件注入到页面中
由于直接require一个css文件后,它的所以选择器的属性都暴露在全局中,会引起干扰,我们需要给他一个命名空间或者私有空间,让他们不会有冲突。
cssModule就是来处理这种问题,可以在css-loader中配置它
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| module.exports = { module: { rules: [{ test: /.\css$/, use: ['style.loader', { loader: 'css-loader', options: { modules: true } }] }] } }
|
这个时候,css中的所有选择器名字都变了不能直接使用,但是require一个css文件, 使用cssModule用它会返回一个class列表, 通过style.[类名]去访问对应样式。
感谢您的阅读,本文由
lynhao 原创提供。如若转载,请注明出处:lynhao(
http://www.lynhao.cn)