Skip to content

Commit

Permalink
[Bugfix] Ensure stability of filename cache-keys
Browse files Browse the repository at this point in the history
`JSON.stringify(structure)` isn’t inherently stable as it relies on various
internal details of how `structure` was created.

As written, if a given babel configuration is create in an dynamic manner,
it is possible for babel-loader to have spurious cache misses.

To address this, we can use one of the many stable stringify alternatives. 

For this PR I have selected [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify)
for that task, as it appears both popular and it’s benchmarks look promising.


This PR does not explicitly include tests, as testing this is both tricky
to test in this context, and the important tests are contained within
fast-json-stable-stringify itself.
  • Loading branch information
stefanpenner committed Jun 9, 2021
1 parent 7fdf6f4 commit 6fb3ede
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 3 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -10,6 +10,7 @@
"node": ">= 8.9"
},
"dependencies": {
"fast-json-stable-stringify": "^2.1.0",
"find-cache-dir": "^3.3.1",
"loader-utils": "^1.4.0",
"make-dir": "^3.1.0",
Expand Down
3 changes: 2 additions & 1 deletion src/cache.js
Expand Up @@ -24,6 +24,7 @@ const writeFile = promisify(fs.writeFile);
const gunzip = promisify(zlib.gunzip);
const gzip = promisify(zlib.gzip);
const makeDir = require("make-dir");
const stringify = require("fast-json-stable-stringify");

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

const contents = JSON.stringify({ source, options, identifier });
const contents = stringify({ source, options, identifier });

hash.update(contents);

Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Expand Up @@ -28,6 +28,7 @@ const schema = require("./schema");
const { isAbsolute } = require("path");
const loaderUtils = require("loader-utils");
const validateOptions = require("schema-utils");
const stringify = require("fast-json-stable-stringify");

function subscribe(subscriber, metadata, context) {
if (context[subscriber]) {
Expand Down Expand Up @@ -186,7 +187,7 @@ async function loader(source, inputSourceMap, overrides) {

const {
cacheDirectory = null,
cacheIdentifier = JSON.stringify({
cacheIdentifier = stringify({
options,
"@babel/core": transform.version,
"@babel/loader": version,
Expand Down
3 changes: 2 additions & 1 deletion yarn.lock
Expand Up @@ -2140,6 +2140,7 @@ __metadata:
eslint-config-prettier: ^6.3.0
eslint-plugin-flowtype: ^5.2.0
eslint-plugin-prettier: ^3.0.0
fast-json-stable-stringify: ^2.1.0
find-cache-dir: ^3.3.1
husky: ^4.3.0
lint-staged: ^10.5.1
Expand Down Expand Up @@ -3711,7 +3712,7 @@ __metadata:
languageName: node
linkType: hard

"fast-json-stable-stringify@npm:^2.0.0":
"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0":
version: 2.1.0
resolution: "fast-json-stable-stringify@npm:2.1.0"
checksum: 7df3fabfe445d65953b2d9d9d3958bd895438b215a40fb87dae8b2165c5169a897785eb5d51e6cf0eb03523af756e3d82ea01083f6ac6341fe16db532fee3016
Expand Down

0 comments on commit 6fb3ede

Please sign in to comment.