前言
最近打算写一款webpack压缩图片的插件,但是需要数据对比,原始数据和压缩后的数据以及压缩的比例相关信息,于是想到了webpack打包的时候不就有相关的输出嘛,于是查看了一下webpack是怎么输出信息的。
输出文件
- 首先在webpack官网看到所有输出的相关信息全部有stats来管理的,自然而安的我们找到webpack源码里面的Stats.js来查找我们想要的信息。 找到toString方法,这个就是我们呢输出文件的调用方法,代码如下
toString(options) {
if (typeof options === "boolean" || typeof options === "string") {
options = Stats.presetToOptions(options);
} else if (!options) {
options = {};
}
const useColors = optionsOrFallback(options.colors, false);
const obj = this.toJson(options, true);
return Stats.jsonToString(obj, useColors);
}
- 接下来我们查看
jsonToString
这个方法
const defaultColors = {
bold: "\u001b[1m",
yellow: "\u001b[1m\u001b[33m",
red: "\u001b[1m\u001b[31m",
green: "\u001b[1m\u001b[32m",
cyan: "\u001b[1m\u001b[36m",
magenta: "\u001b[1m\u001b[35m"
};
可以看到webpack内置了一下输出颜色样式,具体颜色规则可移步这里
然后对defaultColors进行一步处理,代码如下
const colors = Object.keys(defaultColors).reduce(
(obj, color) => {
obj[color] = str => {
if (useColors) {
buf.push(
useColors === true || useColors[color] === undefined
? defaultColors[color]
: useColors[color]
);
}
buf.push(str);
if (useColors) {
buf.push("\u001b[39m\u001b[22m");
}
};
return obj;
},
{
normal: str => buf.push(str)
}
);
得到最终的colors如下
{ normal: [Function: normal],
bold: [Function],
yellow: [Function],
red: [Function],
green: [Function],
cyan: [Function],
magenta: [Function] }
- 然后我们往下继续查找,
[ { value: "Asset", color: colors.bold }, { value: "Size", color: colors.bold }, { value: "Chunks", color: colors.bold }, { value: "", color: colors.bold }, { value: "", color: colors.bold }, { value: "Chunk Names", color: colors.bold }]
这些信息不正是我们webpack默认打包输出的信息嘛,然后继续找,直到我们找到table(t, "rrrlll")
这段代码,我们来看看table
这个函数是干嘛的。具体代码我这边注释如下
/**
*
* @param {Array} array 输出文件的集合
* @param {String} align 排列方式 l左对齐 r右对齐
* @param {String} splitter 在输出的文件左右添加
*/
const table = (array, align, splitter) => {
const rows = array.length; // 输出的行数
const cols = array[0].length; // 输出的列数
const colSizes = new Array(cols);
// 初始化每列最长的字符串长度
for (let col = 0; col < cols; col++) {
colSizes[col] = 0;
}
// 找到每列最长的字符串的长度
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const value = `${getText(array, row, col)}`;
if (value.length > colSizes[col]) {
colSizes[col] = value.length;
}
}
}
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const format = array[row][col].color;
const value = `${getText(array, row, col)}`;
let l = value.length;
if (align[col] === "l") {
format(value);
}
// 该字符串的长度小于本列最长的字符串的话,添加' '
for (; l < colSizes[col] && col !== cols - 1; l++) {
colors.normal(" ");
}
if (align[col] === "r") {
format(value);
}
if (col + 1 < cols && colSizes[col] !== 0) {
colors.normal(splitter || " ");
}
}
// 换行
newline();
}
};
- 最后我们把
buf.join('')
输出出来就是我们所需要的输出样式了
压缩
最后我们测试一下写的压缩图片,测试结果如下: