-
Notifications
You must be signed in to change notification settings - Fork 208
Open
Description
Repository (仓库地址) : css-diff
Gain (收获) : css-diff 是一个对比 css 差异的库,使用它可以对比两个 css 文件的差异。收获见以下源码解析~
// a.css
.a {
font-size: 16px;
color: #fff;
}
// b.css
.a {
font-size: 16px;
color: #fff;
}
.b {
font-weight: normal;
}// index.js
require("css-diff")({
files: ["./a.css", "./b.css"],
omit: ["comment"],
visual: true,
}).then(function (diff) {
console.log(diff.visual); // 见下图
console.log(diff.different); // ture
});源码解析
require("colors");
var cssParse = require("css-parse");
var Promise = require("bluebird");
var Diff = require("diff");
var Compiler = require("./lib/compiler.js");
var Path = require("path");
module.exports = function (options) {
this.options = options;
return (
getContents
.call(this, options.files)
// 将两个css文件的cssom 传递给Diff.diffLines方法进行对比
.spread(Diff.diffLines)
// 生成差异
.then(generateDiff)
.catch(handleError)
);
};
function handleError(e) {
process.stderr.write(("Error: " + e.message + "\n").red.inverse);
process.exit(1);
}
// 核心实现
function generateDiff(diff) {
var different = false;
var visual = diff.reduce(function (prev, part) {
// 判断block是否有差异,很骚的双三元判断
/**
* 新增区域使用绿色渲染差异
* 移除区域使用红色渲染差异
* 灰色代表相同部分
* 总结: 灰色表示相同的部分,绿色表示多出来的部分,红色表示少了的部分.
*/
var color = part.added ? "green" : part.removed ? "red" : "grey";
// 灰色,表示两个文件不存在差异
if (color !== "grey") {
different = true;
}
return prev + part.value[color] + "\n";
}, "");
return {
different: different,
visual: visual,
};
}
function getContents(files) {
var _this = this;
if (files.length < 2) {
return new Error("you must pass 2 file paths in");
}
return Promise.all(
files.map(function (path) {
return Compiler(Path.resolve(path)).then(function (css) {
// 获取css字符串,使用cssParse将css字符串转换为CSSOM
// css string -> cssom
var rules = cssParse(css).stylesheet.rules; // 输出结果可见下图
// 返回 序列化后的 过滤omit参数选项的cssom规则类型数组
// 这里有个小技巧,JSON.stringify使用了space参数,用于在输出JSON字符串中插入空格以提高可读性。
return JSON.stringify(
rules.filter(function (rule) {
return !~_this.options.omit.indexOf(rule.type);
}),
null,
4
);
});
})
);
}a.css,b.css cssom rules output
思考
// 以下代码,你觉得输出的会是什么呢?
require("css-diff")({
files: ["./b.css", "./a.css"],
omit: ["comment"],
visual: true,
}).then(function (diff) {
console.log(diff.visual);
console.log(diff.different);
});Metadata
Metadata
Assignees
Labels
No labels

