webpack/tooling/print-cache-file.js

156 lines
4.5 KiB
JavaScript
Raw Normal View History

2018-10-09 20:30:59 +08:00
const path = require("path");
2019-08-09 20:42:59 +08:00
const fs = require("fs");
2018-10-09 20:30:59 +08:00
const BinaryMiddleware = require("../lib/serialization/BinaryMiddleware");
const FileMiddleware = require("../lib/serialization/FileMiddleware");
const Serializer = require("../lib/serialization/Serializer");
const SerializerMiddleware = require("../lib/serialization/SerializerMiddleware");
2018-10-09 20:30:59 +08:00
const binaryMiddleware = new BinaryMiddleware();
const serializer = new Serializer([binaryMiddleware, new FileMiddleware(fs)]);
2018-10-09 20:30:59 +08:00
const rawSerializer = new Serializer([new FileMiddleware(fs)]);
const lazySizes = [];
const captureSize = async data => {
let size = 0;
let lazySize = 0;
for (const b of data) {
if (Buffer.isBuffer(b)) {
size += b.length;
} else if (typeof b === "function") {
const i = lazySizes.length;
lazySizes.push(undefined);
const r = await captureSize(await b());
lazySize += r.size + r.lazySize;
// eslint-disable-next-line require-atomic-updates
lazySizes[i] = r;
}
}
return { size, lazySize };
};
2018-10-09 20:30:59 +08:00
const ESCAPE = null;
2018-10-10 15:55:06 +08:00
const ESCAPE_ESCAPE_VALUE = null;
const ESCAPE_END_OBJECT = true;
const ESCAPE_UNDEFINED = false;
2018-10-09 20:30:59 +08:00
const printData = async (data, indent) => {
if (!Array.isArray(data)) throw new Error("Not an array");
if (Buffer.isBuffer(data[0])) {
for (const b of data) {
if (typeof b === "function") {
const innerData = await b();
const info = lazySizes.shift();
const sizeInfo = `${(info.size / 1048576).toFixed(2)} MiB + ${(
info.lazySize / 1048576
).toFixed(2)} lazy MiB`;
console.log(`${indent}= lazy ${sizeInfo} {`);
2018-10-09 20:30:59 +08:00
await printData(innerData, indent + " ");
console.log(`${indent}}`);
} else {
console.log(`${indent}= ${b.toString("hex")}`);
}
}
return;
}
const referencedValues = new Map();
const referencedTypes = new Map();
let currentReference = 0;
let currentTypeReference = 0;
2018-10-09 20:30:59 +08:00
let i = 0;
const read = () => {
return data[i++];
};
2018-10-10 15:55:06 +08:00
const printLine = content => {
console.log(`${indent}${content}`);
};
printLine(`Version: ${read()}`);
2018-10-09 20:30:59 +08:00
while (i < data.length) {
const item = read();
if (item === ESCAPE) {
const nextItem = read();
if (nextItem === ESCAPE_ESCAPE_VALUE) {
2018-10-10 16:25:05 +08:00
printLine("null");
2018-10-09 20:30:59 +08:00
} else if (nextItem === ESCAPE_UNDEFINED) {
2018-10-10 16:25:05 +08:00
printLine("undefined");
2018-10-09 20:30:59 +08:00
} else if (nextItem === ESCAPE_END_OBJECT) {
indent = indent.slice(0, indent.length - 2);
2018-10-10 15:55:06 +08:00
printLine(`} = #${currentReference++}`);
} else if (typeof nextItem === "number" && nextItem < 0) {
const ref = currentReference + nextItem;
const value = referencedValues.get(ref);
if (value) {
printLine(
`Reference ${nextItem} => ${JSON.stringify(value)} #${ref}`
);
} else {
printLine(`Reference ${nextItem} => #${ref}`);
}
2018-10-09 20:30:59 +08:00
} else {
const request = nextItem;
2018-10-10 15:55:06 +08:00
if (typeof request === "number") {
const ref = currentTypeReference - request;
2018-10-10 15:55:06 +08:00
printLine(
`Object (Reference ${request} => ${referencedTypes.get(
ref
)} @${ref}) {`
);
} else {
2018-10-10 15:55:06 +08:00
const name = read();
referencedTypes.set(currentTypeReference, `${request} / ${name}`);
2018-10-10 15:55:06 +08:00
printLine(
2018-10-10 16:25:05 +08:00
`Object (${request} / ${name} @${currentTypeReference++}) {`
);
}
2018-10-09 20:30:59 +08:00
indent += " ";
}
} else if (typeof item === "string") {
2018-10-10 16:24:44 +08:00
if (item !== "") {
referencedValues.set(currentReference, item);
2018-10-10 16:25:05 +08:00
printLine(`${JSON.stringify(item)} = #${currentReference++}`);
2018-10-10 16:24:44 +08:00
} else {
2018-10-10 16:25:05 +08:00
printLine('""');
2018-10-10 16:24:44 +08:00
}
2018-10-09 20:30:59 +08:00
} else if (Buffer.isBuffer(item)) {
2018-10-10 16:25:05 +08:00
printLine(`buffer ${item.toString("hex")} = #${currentReference++}`);
2018-10-09 20:30:59 +08:00
} else if (typeof item === "function") {
const innerData = await item();
if (!SerializerMiddleware.isLazy(item, binaryMiddleware)) {
const info = lazySizes.shift();
const sizeInfo = `${(info.size / 1048576).toFixed(2)} MiB + ${(
info.lazySize / 1048576
).toFixed(2)} lazy MiB`;
printLine(`lazy-file ${sizeInfo} {`);
} else {
printLine(`lazy-inline {`);
}
2018-10-09 20:30:59 +08:00
await printData(innerData, indent + " ");
2018-10-10 15:55:06 +08:00
printLine(`}`);
} else {
2018-10-10 16:25:05 +08:00
printLine(`${item}`);
2018-10-09 20:30:59 +08:00
}
}
};
const filename = process.argv[2];
(async () => {
const structure = await rawSerializer.deserialize(null, {
filename: path.resolve(filename),
extension: ".pack"
});
const info = await captureSize(structure);
const sizeInfo = `${(info.size / 1048576).toFixed(2)} MiB + ${(
info.lazySize / 1048576
).toFixed(2)} lazy MiB`;
console.log(`${filename} ${sizeInfo}:`);
2018-10-09 20:30:59 +08:00
const data = await serializer.deserialize(null, {
filename: path.resolve(filename),
extension: ".pack"
});
await printData(data, "");
})();