Skip to content

Commit

Permalink
polish: use our own config serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Jul 11, 2024
1 parent 2237bd6 commit 698265a
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 12 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"node": ">= 14.15.0"
},
"dependencies": {
"fast-stable-stringify": "^1.0.0",
"find-cache-dir": "^4.0.0",
"schema-utils": "^4.0.0"
},
Expand Down
6 changes: 3 additions & 3 deletions src/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ const zlib = require("zlib");
const crypto = require("crypto");
const { promisify } = require("util");
const { readFile, writeFile, mkdir } = require("fs/promises");
// Lazily instantiated when needed
const findCacheDirP = import("find-cache-dir");

const transform = require("./transform");
// Lazily instantiated when needed
const serialize = require("./serialize");
let defaultCacheDirectory = null;

let hashType = "sha256";
Expand All @@ -29,7 +30,6 @@ try {

const gunzip = promisify(zlib.gunzip);
const gzip = promisify(zlib.gzip);
const stringify = require("fast-stable-stringify");

/**
* Read the contents from the compressed file.
Expand Down Expand Up @@ -71,7 +71,7 @@ const write = async function (filename, compress, result) {
const filename = function (source, identifier, options) {
const hash = crypto.createHash(hashType);

hash.update(stringify({ source, options, identifier }));
hash.update(serialize([options, source, identifier]));

return hash.digest("hex") + ".json";
};
Expand Down
83 changes: 83 additions & 0 deletions src/serialize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
var objToString = Object.prototype.toString;
var objKeys = Object.getOwnPropertyNames;

/**
* A custom Babel options serializer
*
* Intentional deviation from JSON.stringify:
* 1. Object properties are sorted before seralizing
* 2. The output is NOT a valid JSON: e.g.
* The output does not enquote strings, which means a JSON-like string '{"a":1}'
* will share the same result with an JS object { a: 1 }. This is not an issue
* for Babel options, but it can not be used for general serialization purpose
* 3. Only 20% slower than the native JSON.stringify on V8
*
* This function is a fork from https://github.com/nickyout/fast-stable-stringify
* @param {*} val Babel options
* @param {*} isArrayProp
* @returns serialized Babel options
*/
function serialize(val, isArrayProp) {
var i, max, str, keys, key, propVal, toStr;
if (val === true) {
return "!0";
}
if (val === false) {
return "!1";
}
switch (typeof val) {
case "object":
if (val === null) {
return null;
} else if (val.toJSON && typeof val.toJSON === "function") {
return serialize(val.toJSON(), isArrayProp);
} else {
toStr = objToString.call(val);
if (toStr === "[object Array]") {
str = "[";
max = val.length - 1;
for (i = 0; i < max; i++) {
str += serialize(val[i], true) + ",";
}
if (max > -1) {
str += serialize(val[i], true);
}
return str + "]";
} else if (toStr === "[object Object]") {
// only object is left
keys = objKeys(val).sort();
max = keys.length;
str = "{";
i = 0;
while (i < max) {
key = keys[i];
propVal = serialize(val[key], false);
if (propVal !== undefined) {
if (str) {
str += ",";
}
str += '"' + key + '":' + propVal;
}
i++;
}
return str + "}";
} else {
return JSON.stringify(val);
}
}
case "function":
case "undefined":
return isArrayProp ? null : undefined;
case "string":
return val;
default:
return isFinite(val) ? val : null;
}
}

module.exports = function (val) {
var returnVal = serialize(val, false);
if (returnVal !== undefined) {
return "" + returnVal;
}
};
2 changes: 2 additions & 0 deletions test/cache.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,5 +323,7 @@ test("should allow to specify the .babelrc file", async t => {
t.deepEqual(multiStats.stats[1].compilation.warnings, []);

const files = fs.readdirSync(t.context.cacheDirectory);
// The two configs resolved to same Babel config because "fixtures/babelrc"
// is { "presets": ["@babel/preset-env"] }
t.true(files.length === 1);
});
8 changes: 0 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2283,7 +2283,6 @@ __metadata:
eslint: ^9.6.0
eslint-config-prettier: ^9.1.0
eslint-plugin-prettier: ^5.1.3
fast-stable-stringify: ^1.0.0
find-cache-dir: ^4.0.0
globals: ^15.8.0
husky: ^8.0.3
Expand Down Expand Up @@ -3556,13 +3555,6 @@ __metadata:
languageName: node
linkType: hard

"fast-stable-stringify@npm:^1.0.0":
version: 1.0.0
resolution: "fast-stable-stringify@npm:1.0.0"
checksum: ef1203d246a7e8ac15e2bfbda0a89fa375947bccf9f7910be0ea759856dbe8ea5024a0d8cc2cceabe18a9cb67e95927b78bb6173a3ae37ec55a518cf36e5244b
languageName: node
linkType: hard

"fastq@npm:^1.6.0":
version: 1.17.1
resolution: "fastq@npm:1.17.1"
Expand Down

0 comments on commit 698265a

Please sign in to comment.