Files
skeleton/scripts/generate-jss.js

75 lines
2.6 KiB
JavaScript

#!/usr/bin/env node
import { generateAllTWClasses, transpileCssToJs } from './compile-css-to-js.cjs';
import { mkdir, writeFile, rename, unlink } from 'fs/promises';
const INTELLISENSE_FILE_NAME = 'intellisense-classes.cjs';
exec();
async function exec() {
// Deletes the previously generated CSS-in-JS file. If we don't, our plugin will
// add duplicate classes to our newly generated CSS-in-JS file.
await unlink(`src/lib/tailwind/generated/${INTELLISENSE_FILE_NAME}`).catch(() => {
// file doesn't exist, don't worry about it
});
// Makes directory that's used for caching
await mkdir('.temp').catch(() => {
// directory already exists
});
// Makes directory that stores our generated CSS-in-JS
await mkdir('src/lib/tailwind/generated').catch(() => {
// directory already exists
});
const generatedJSS = await transpileCssToJs();
const purgedJSS = await removeDuplicateClasses(generatedJSS);
// Creates the generated CSS-in-JS file
await writeFile(`src/lib/tailwind/generated/${INTELLISENSE_FILE_NAME}`, `module.exports = ${JSON.stringify(purgedJSS)}`).catch((e) =>
console.error(e)
);
// A roundabout 'hack' to retrigger the tailwind extension to reload,
// otherwise we'd have to reload vscode manually.
await rename('tailwind.config.cjs', '.temp/tailwind.config.cjs');
// We need to sleep for a bit so that the change is detected
// by the extension's file watcher
await new Promise((resolve) => setTimeout(resolve, 3000));
await rename('.temp/tailwind.config.cjs', 'tailwind.config.cjs');
}
// Purges the generated CSS-in-JS file of duplicate TW classes
async function removeDuplicateClasses(cssInJs) {
let twClasses;
try {
// import the cached TW classes...
const classes = await import('../.temp/twClasses.cjs');
twClasses = classes.default;
} catch {
// if the cache doesn't exist (first time install), generate it
twClasses = await generateAllTWClasses();
}
// We delete classes that have 'token' and 'bg-' in their name since those classes
// will already be generated by our plugin. We'll also delete any default TW classes.
for (const [key] of Object.entries(cssInJs)) {
// if it's a token, delete it
if (key.includes('token')) delete cssInJs[key];
// if it's a background color, delete it
if (key.includes('bg-')) delete cssInJs[key];
// if it's not a class selector, delete it (only want classes in the intellisense)
if (key[0] !== '.') delete cssInJs[key];
// deletes the dark variant of type selectors (ex: .dark body {...})
if (key.startsWith('.dark') && key[6] !== '.') delete cssInJs[key];
// if it's a default tailwind class, delete it
if (twClasses[key]) delete cssInJs[key];
}
return cssInJs;
}