Skip to content

Commit

Permalink
feat: add cache invalidation on update of nearest .babelrc update
Browse files Browse the repository at this point in the history
  • Loading branch information
mellyeliu committed Jan 17, 2025
1 parent 67835a4 commit 5db7b69
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
24 changes: 24 additions & 0 deletions packages/cli/__tests__/compile-stylex-folder-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ describe('cache mechanism works as expected', () => {

beforeAll(async () => {
await fs.rm(cachePath, { recursive: true, force: true });
await fs.writeFile(path.join(process.cwd(), '.babelrc'), JSON.stringify({ presets: ['@babel/preset-env'] }, null, 2));
});

beforeEach(() => {
Expand All @@ -274,6 +275,7 @@ describe('cache mechanism works as expected', () => {
afterAll(async () => {
await fs.rm(config.output, { recursive: true, force: true });
await fs.rm(cachePath, { recursive: true, force: true });
await fs.rm(path.join(process.cwd(), '.babelrc'));
});

test('first compilation populates the cache', async () => {
Expand Down Expand Up @@ -329,6 +331,28 @@ describe('cache mechanism works as expected', () => {
}
});

test('recompiles when babelrc changes', async () => {
await fs.writeFile(path.join(process.cwd(), '.babelrc'), JSON.stringify({ presets: ['@babel/preset-react'] }, null, 2));
await compileDirectory(config);

// Ensure cache is rewritten due to cache invalidation
expect(writeSpy).toHaveBeenCalledTimes(3);

const cacheFiles = await fs.readdir(cachePath);
expect(cacheFiles.length).toEqual(3);

for (const cacheFile of cacheFiles) {
const cacheFilePath = path.join(cachePath, cacheFile);
const cacheContent = JSON.parse(
await fs.readFile(cacheFilePath, 'utf-8'),
);
expect(cacheContent).toHaveProperty('inputHash');
expect(cacheContent).toHaveProperty('outputHash');
expect(cacheContent).toHaveProperty('collectedCSS');
expect(cacheContent).toHaveProperty('configHash');
}
});

test('recompiles when input changes', async () => {
const mockFilePath = path.join(config.input, 'index.js');
const mockFileOutputPath = path.join(config.output, 'index.js');
Expand Down
34 changes: 34 additions & 0 deletions packages/cli/src/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ export function getDefaultCachePath() {
return path.join('node_modules', '.stylex-cache');
}

async function findNearestBabelRC(dir) {
let currentDir = dir;

while (currentDir !== path.parse(currentDir).root) {
const babelrcPath = path.join(currentDir, '.babelrc');
try {
await fs.access(babelrcPath);
console.log('Found babelrc:', babelrcPath);
return babelrcPath;
} catch {
currentDir = path.dirname(currentDir);
}
}
console.log('Found no babelrc:');
return null;
}


export async function getCacheFilePath(cachePath, filePath) {
const projectRoot = path.resolve(__dirname, '../../../');
const absoluteFilePath = path.resolve(filePath);
Expand Down Expand Up @@ -60,6 +78,22 @@ export async function deleteCache(cachePath, filePath) {
}
}

export async function computeBabelRCHash(path) {
const babelPath = await findNearestBabelRC(path);
if (!babelPath) {
return null; // No .babelrc found
}

try {
const fileBuffer = await fs.readFile(babelPath);
const fileContent = fileBuffer.toString('utf8');
return hash(fileContent);
} catch (error) {
console.error(`Error reading or hashing file: ${error.message}`);
throw error;
}
}

export function computeStyleXConfigHash(config) {
// Excluding `input` and `output` paths to hash config settings
const configOptions = Object.fromEntries(
Expand Down
5 changes: 5 additions & 0 deletions packages/cli/src/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
readCache,
computeFilePathHash,
computeStyleXConfigHash,
computeBabelRCHash,
getDefaultCachePath,
} from './cache';
import {
Expand Down Expand Up @@ -110,6 +111,8 @@ export async function compileFile(
}

const configHash = computeStyleXConfigHash(config);
const babelHash = await computeBabelRCHash(inputFilePath);
console.log(`[stylex] babelHash: ${babelHash}`)

const cacheData = await readCache(cachePath, filePath);

Expand All @@ -119,6 +122,7 @@ export async function compileFile(
oldOutputHash &&
cacheData.outputHash === oldOutputHash &&
cacheData.configHash === configHash
&& cacheData.babelHash === babelHash
) {
console.log(`[stylex] Using cached CSS for: ${filePath}`);
config.state.styleXRules.set(filePath, cacheData.collectedCSS);
Expand All @@ -144,6 +148,7 @@ export async function compileFile(
outputHash: newOutputHash,
collectedCSS: rules,
configHash,
babelHash,
});
}
}
Expand Down

0 comments on commit 5db7b69

Please sign in to comment.