From ef2a887020fca3e5a166f0c581dd2c40d4f4c8d9 Mon Sep 17 00:00:00 2001 From: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Date: Sat, 21 Jan 2023 07:15:38 -0500 Subject: [PATCH 1/2] Always sort candidates --- src/lib/expandTailwindAtRules.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/lib/expandTailwindAtRules.js b/src/lib/expandTailwindAtRules.js index 295bbc3dc9d0..cc8c09d74704 100644 --- a/src/lib/expandTailwindAtRules.js +++ b/src/lib/expandTailwindAtRules.js @@ -163,19 +163,15 @@ export default function expandTailwindAtRules(context) { let classCacheCount = context.classCache.size env.DEBUG && console.time('Generate rules') - // TODO: Sorting is _probably_ slow, but right now it can guarantee the same order. Eventually - // we will be able to get rid of this. + // TODO: This has a small cost but is needed to make builds deterministic. Move this to Rust eventually. env.DEBUG && console.time('Sorting candidates') - let sortedCandidates = - typeof process !== 'undefined' && process.env.JEST_WORKER_ID - ? new Set( - [...candidates].sort((a, z) => { - if (a === z) return 0 - if (a < z) return -1 - return 1 - }) - ) - : candidates + let sortedCandidates = new Set( + [...candidates].sort((a, z) => { + if (a === z) return 0 + if (a < z) return -1 + return 1 + }) + ) env.DEBUG && console.timeEnd('Sorting candidates') generateRules(sortedCandidates, context) env.DEBUG && console.timeEnd('Generate rules') From b4d2f104ac13e98814152532ea51a7024f71db74 Mon Sep 17 00:00:00 2001 From: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Date: Sat, 21 Jan 2023 07:31:24 -0500 Subject: [PATCH 2/2] Sort candidates in Rust in Oxide engine --- oxide/crates/core/src/lib.rs | 6 ++++-- src/lib/expandTailwindAtRules.js | 17 +++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/oxide/crates/core/src/lib.rs b/oxide/crates/core/src/lib.rs index d190af3c2a85..84713e61bc58 100644 --- a/oxide/crates/core/src/lib.rs +++ b/oxide/crates/core/src/lib.rs @@ -54,7 +54,7 @@ fn parse_all_blobs(blobs: Vec>) -> Vec { let input: Vec<_> = blobs.iter().map(|blob| &blob[..]).collect(); let input = &input[..]; - input + let mut result: Vec = input .par_iter() .map(|input| Extractor::unique(input, Default::default())) .reduce(Default::default, |mut a, b| { @@ -68,5 +68,7 @@ fn parse_all_blobs(blobs: Vec>) -> Vec { // to a string. unsafe { String::from_utf8_unchecked(s.to_vec()) } }) - .collect() + .collect(); + result.sort(); + result } diff --git a/src/lib/expandTailwindAtRules.js b/src/lib/expandTailwindAtRules.js index cc8c09d74704..d4688f74c929 100644 --- a/src/lib/expandTailwindAtRules.js +++ b/src/lib/expandTailwindAtRules.js @@ -163,15 +163,16 @@ export default function expandTailwindAtRules(context) { let classCacheCount = context.classCache.size env.DEBUG && console.time('Generate rules') - // TODO: This has a small cost but is needed to make builds deterministic. Move this to Rust eventually. env.DEBUG && console.time('Sorting candidates') - let sortedCandidates = new Set( - [...candidates].sort((a, z) => { - if (a === z) return 0 - if (a < z) return -1 - return 1 - }) - ) + let sortedCandidates = env.OXIDE + ? candidates + : new Set( + [...candidates].sort((a, z) => { + if (a === z) return 0 + if (a < z) return -1 + return 1 + }) + ) env.DEBUG && console.timeEnd('Sorting candidates') generateRules(sortedCandidates, context) env.DEBUG && console.timeEnd('Generate rules')