// Builds all styles into `css` as `*.css` and `*.user.css` files. const { execSync } = require('child_process'); const { join } = require('path'); const { moveSync, mkdirpSync, readdirSync, readFileSync, removeSync, writeFileSync } = require('fs-extra'); const { create } = require('usercss-creator'); if (!process.env.STYLE_ENV) { throw new Error('Environment variable STYLE_ENV is not set.'); } const tempPath = join(__dirname, 'temp'); const logMeta = process.env.STYLE_ENV === 'dev' ? '[build]'.padEnd(10) : '[build] '; // If we're in prod then clear the temp folder to avoid unwanted files going into `css` if (process.env.STYLE_ENV === 'prod') { console.log(logMeta + 'building for production, see `css/` for output'); removeSync(tempPath); } console.log(`${logMeta}reading \`${join(__dirname, 'src')}\` files`); let cssFiles = readdirSync(join(__dirname, 'src')); // Generate all the SCSS using the CLI console.log(logMeta + 'generating SASS/SCSS -> CSS'); const outputStyle = process.env.STYLE_ENV === 'dev' ? 'expanded' : 'compressed'; mkdirpSync('temp/'); for (const cssFile of cssFiles) { execSync(`yarn sass --no-source-map --style ${outputStyle} src/${cssFile}/${cssFile}.s* ${tempPath}/${cssFile}.css`); console.log(`${logMeta}✔ ${cssFile}`); } console.log(`${logMeta}reading \`${tempPath}\` files`); cssFiles = readdirSync(tempPath); console.log(logMeta + 'generating CSS -> UserCSS'); for (const cssFile of cssFiles) { // Only generate non-usercss files if (cssFile.endsWith('.user.css')) { continue; } const cssPath = join(tempPath, cssFile); // This uses the css file's name to resolve the appropriate `package.json` // All CSS files have the same name as their directory const packagePath = join(__dirname, 'src', cssFile.substring(0, cssFile.indexOf('.')), 'package.json'); const { usercss } = JSON.parse(readFileSync(packagePath, 'UTF8')); // We don't specify an output path because we just want it generated next to the regular CSS file create(cssPath, usercss); } cssFiles = readdirSync(tempPath); // Add `@-moz-document domain(...)` to all the `.user.css` files for (const cssFile of cssFiles) { if (!cssFile.endsWith('.user.css')) { continue; } const cssPath = join(tempPath, cssFile); const packagePath = join(__dirname, 'src', cssFile.substring(0, cssFile.indexOf('.')), 'package.json'); const { usercss } = JSON.parse(readFileSync(packagePath, 'UTF8')); let css = readFileSync(cssPath, 'UTF8'); const usercssIndex = css.indexOf('==/UserStyle== */'); const usercssLength = '==/UserStyle== */'.length; css = css.substring(0, usercssIndex + usercssLength) + `\n@-moz-document domain("${usercss.namespace}") {\n` + css.substring(usercssIndex + usercssLength + 1, css.length) + '}\n'; writeFileSync(cssPath, css); console.log(`${logMeta}✔ ${cssFile} v${usercss.version}`); } // If we're in prod, we now wanna move all the files into `css` if (process.env.STYLE_ENV === 'prod') { cssFiles = readdirSync(tempPath); console.log(`${logMeta}moving ${cssFiles.length} generated files`); for (const cssFile of cssFiles) { const cssPath = join(tempPath, cssFile); const prodPath = join(__dirname, 'css'); const dirPath = join(prodPath, cssFile.substring(0, cssFile.indexOf('.'))); // `mkdir -p ` to create any directories that don't exist yet mkdirpSync(dirPath); moveSync(cssPath, join(dirPath, cssFile), { overwrite: true }); } removeSync(tempPath); } console.log(logMeta + 'finished 😁');