虽然本项目名称中出现了gulp,但是,千万不要误导。实际上,gulp只是偏角一隅,本项目不仅支持gulp使用,还支持纯node.js使用,还支持web版使用等。
自己弄的一个Node.js小工具,本打算作为私藏水果刀平时随便用用,一番折腾和试用,发现原来是把斩仙刀,可以好好整整推一推。
QCSS是Quick CSS的缩写,寓意是CSS书写快步如飞!
平常我们写CSS是这样:
.class-a {
width: 300px;
height: 150px;
position: absolute;
left: 100px;
top: 100px;
}
如果QCSS书写,则是:
.class-a {
w300; h150; abs; l100; t100;
}
少写了好多代码,感觉自己又年轻了许多。
下面视频为QCSS编译为CSS的录屏,实际上书写的时候是一次保存,全部编译,视频为了演示,每写一句编译了一次。
QCSS本质上也是个预编译工具,和Less,Stylus工具相比,更专注于CSS快速书写能力,嵌套,函数全部都不支持,但支持自定义变量。
更专注意味着更简单,更高效,同时在书写这一块更极致。
简单高效:基于映射规则的字符替换,无任何依赖,仅几K JS大小,移植到web上几乎无成本;
书写极致:可以自定义属性缩写,还可以自定义属性值缩写,甚至还可以自定义多个CSS声明片段缩写。仅需要分号分隔,px单位默认可缺省。
项目根目录下的node-qcss.js
中有两个变量,为pathSrcQcss
和pathDistQcss
,分别对应QCSS文件目录和编译出来的CSS文件所在目录。
只要配置这两个路径为你所需要的路径。然后,直接下面这一句就可以使用了:
node node-qcss
直接node-qcss.js
这个JS就可以了,可以在任意目录位置,运行后,自动QCSS编译并开启资源监控,非常轻便轻量。
默认node-qcss.js
会在同目录下寻找qcss-web
这个模块,如果没有,就会直接在线拉取最新的qcss-map
和qcss-web
这两个模块(只会执行一次)。
因此,实际开发只需要:
node-qcss.js
放在合适位置;- 配置其中
pathSrcQcss
和pathDistQcss
的路径值; node node-qcss
运行;
就完成啦,非常简单轻便!
gulp插件核心代码为根目录下的index.js
实际使用,步骤如下:
- 按照
gulp-qcss
插件:
npm install gulp-qcss
- 注册任务:
var gulp = require('gulp');
var qcss = require('gulp-qcss');
// gulp任务
gulp.task('default', function () {
gulp.src('src/test.qcss')
.pipe(qcss()) // 或者.pipe(qcss('sass')) 如果有需要的话,默认是.css后缀
.pipe(gulp.dest('dist/'));
});
然后就可以啦!具体可以参见/test/
目录中的测试兼演示。
主要是项目根目录下的qcss-web.js
。默认为模块化加载:
module.exports = function (data) {
}
如果希望直连,可以改造下:
var qcss2css = function (data) {
}
其中data
指QCSS字符内容,返回的是编译后的CSS字符内容。
如果直连,则依赖的qcss-map.js
也要内联到qcss-web.js
中。
本质上Qcss是个解析器,因此,无法作为postcss插件使用。使用示意:
let qcss = require('../qcss-web.js');
const postcss = require('postcss');
const fs = require('fs')
let parse = (css, opts = {}) => {
return postcss.parse(qcss(css), opts);
}
fs.readFile(__dirname + '/src/test.qcss', 'utf-8', (err, css) => {
postcss([{
postcssPlugin: 'postcss-qcss'
}]).process(css, {
from: __dirname + '/src/test.qcss',
to: __dirname + '/dest/test.css',
parser: parse
})
.then(result => {
fs.writeFile(__dirname + '/dest/test.css', result.css, (err) => {
if (!err) {
console.log('dest/test.css编译成功');
}
})
}).catch(error => {
console.error(error)
})
})
详见 ./test-postcss-qcss/run.js
可以执行下面的命令体验:
npm install
node test-postcss-qcss/run
本质上就是个正则替换。
我们对HTML字符进行转义的时候,会这么处理,一个映射对象,一个正则替换,如下:
var keyMap = {
'<': '<',
'>': '>',
'&': '&'
};
xxx.replace(/<|&|>/g, function(matchs) {
return keyMap[matchs];
});
QCSS的实现也是如此:
keyMap = {
dn: 'display: none',
db: 'display: block',
m: 'margin: ',
ml: 'margin-left: ',
…
};
css = qcss.replace(/* 替换细节 */);
· QCSS支持CSS属性缩写替换,例如:width -> w
· QCSS支持CSS声明缩写替换,例如:display: none -> dn
· QCSS支持多个CSS声明替换,例如:text-overflow: ellipsis; white-space: nowrap; overflow: hidden -> ell
不仅如此,QCSS还支持属性值关键字的映射,例如:color: currentColor -> c cc
,前面的c
是color
属性的缩写,后面的cc
是currentColor
关键字的缩写。
完整映射规则可参见:/qcss-map.js
内置的规则为自己多年缩写习惯,很多命名都是借鉴zxx.lib.css[https://github.com/zhangxinxu/zxx.lib.css] 由于不是粉色的(指人民币),不可能所有人都喜欢这样的命名规则,所以,建议可以根据自己的习惯和喜好进行修改,添加。
QCSS还支持自定义属性值变量,变量的声明是在注释中,变量名$
开头,可以使用等号或冒号连接变量值,例如:
/*
$blue = #00a050;
$light = #eee;
$font: 'Microsoft yahei';
*/
会替换下面这个:
.class { bg light; ff font;}
为下面这样:
.class {
background: #eee;
font-family: 'Microsoft yahei'
}
根据实际测试,QCSS文件比CSS文件体积可以小30%~50%(试选择器复杂度),很多人会表示,反正最后上线的都是CSS文件,哪怕你QCSS文件小80%也没有意义啊,其实不然。
由于Service Worker的存在,我们可以把QCSS直接注册在浏览器中,于是我们可以直接请求.qcss
文件,节省流量传输。
为此,我特意写了个创新的CSS压缩工具,css2qcss.js
,可以把目前的标准的CSS文件全部压缩成QCSS这种缩写形式,配合Service Worker,就可以让网站在CSS资源这块的传输小30%~50%,注意,这是相比压缩的CSS文件的数据,如果是开发版的CSS,则压缩率甚至可以到60%,比JavaScript主流压缩工具还要厉害。
该压缩工具核心方法见:/css2qcss.js
,依赖映射模块/qcss-map.js
和CSS压缩模块/mini/cssmin.js
。
然后自己想要压缩文件的时候,读写文件即可,具体案例可参见:https://github.com/zhangxinxu/gulp-qcss/blob/master/mini/run.js
代码如下:
/**
* 压缩测试的脚本
*/
const fs = require('fs');
const css2qcss = require('../css2qcss');
fs.readFile('./test/extra.css', 'utf8', (err, data) => {
let length = data.length;
//去除注释
data = css2qcss(data);
fs.writeFile('./test/extra.qcss', data, function () {
console.log('extra.qcss压缩成功,尺寸减小了:' +
Math.round(10000 * (length - data.length) / length) / 100 +
'%');
});
});