UNPKG

@spectrum-css/bundle-builder

Version:

The Spectrum CSS top-level builder

201 lines (171 loc) 4.81 kB
const gulp = require("gulp"); const path = require("path"); const rename = require("gulp-rename"); const concat = require("gulp-concat"); const through = require("through2"); const postcss = require("postcss"); const dirs = require("../lib/dirs.js"); const destination = path.join(__dirname, "../../../dist"); const varDir = path.dirname(require.resolve("@spectrum-css/vars/package.json", { paths: [process.cwd(), path.join(process.cwd(), "../../")] })); const expressVarDir = path.dirname(require.resolve("@spectrum-css/expressvars/package.json", { paths: [process.cwd(), path.join(process.cwd(), "../../")] })); const coreTokensDir = path.dirname(require.resolve("@spectrum-css/tokens/package.json", { paths: [process.cwd(), path.join(process.cwd(), "../../")] })) ?? path.dirname(dirs.components, "tokens"); // Uhg share this with component-builder function getVarsFromCSS(css) { let variableList = {}; let root = postcss.parse(css); root.walkRules((rule) => { rule.walkDecls((decl) => { let matches = decl.value.match(/--[\w-]+/g); if (matches) { matches.forEach(function (match) { variableList[match] = true; }); } }); }); return variableList; } function getVarValues(css) { let root = postcss.parse(css); let variables = {}; root.walkRules((rule) => { rule.walkDecls((decl) => { variables[decl.prop] = decl.value; }); }); return variables; } function getAllVars() { return new Promise((resolve, reject) => { let variableList; gulp .src([ `${varDir}/css/themes/*.css`, `${varDir}/css/scales/*.css`, `${varDir}/css/components/*.css`, `${varDir}/css/globals/*.css`, `${coreTokensDir}/dist/index.css`, ]) .pipe(concat("everything.css")) .pipe( through.obj(function getAllVars(file, enc, cb) { variableList = getVarValues(file.contents.toString()); cb(null, file); }) ) .on("finish", () => { resolve(variableList); }) .on("error", reject); }); } function resolveValue(value, vars) { if (value) { let match = value.match(/var\((.+),?.*?\)/); if (match) { return match[1]; } return value; } } function getUsedVars() { return new Promise(async (resolve, reject) => { let variableArray; let variableObject; let allVars = await getAllVars(); gulp .src(`${dirs.components}/*/dist/index-vars.css`) .pipe(concat("everything.css")) .pipe( through.obj(function getUsedVars(file, enc, cb) { variableObject = getVarsFromCSS(file.contents.toString()); // Resolve each variable to ensure everything it references is available for (let varName in variableObject) { let reffedVar = allVars[varName]; if (reffedVar && reffedVar.startsWith("var")) { let value = resolveValue(reffedVar); let curVarName = value; while (allVars[curVarName]) { if (!variableObject[curVarName]) { variableObject[curVarName] = true; } curVarName = allVars[curVarName]; } } } variableArray = Object.keys(variableObject); cb(null, file); }) ) .on("finish", () => { resolve(variableArray); }) .on("error", reject); }); } function buildUnique() { return new Promise(async (resolve, reject) => { // Read in all variables from components let variableList = await getUsedVars(); // For each stop and scale, filter by used variables only gulp .src([ path.join(varDir, "dist/*.css"), "!" + path.join(varDir, "dist/index.css") ], { allowEmpty: true }) .pipe( through.obj(function makeUnique(file, enc, cb) { let css = file.contents.toString(); let root = postcss.parse(css); root.walkRules((rule) => { rule.walkDecls((decl) => { if (variableList.indexOf(decl.prop) === -1) { decl.remove(); } }); }); file.contents = Buffer.from(root.toString()); // For each line variable, delete it if its not included cb(null, file); }) ) .pipe( rename((file) => { file.basename += "-unique"; }) ) .pipe(gulp.dest(`${destination}/dependencies/@spectrum-css/vars/`)) .on("finish", resolve) .on("error", reject); }); } function copyVars() { return gulp .src(path.join(varDir, "dist/spectrum-*.css")) .pipe(gulp.dest(`${destination}/dependencies/@spectrum-css/vars/`)); } function copyExpressVars() { return gulp .src(path.join(expressVarDir, "dist/spectrum-*.css")) .pipe(gulp.dest(`${destination}/dependencies/@spectrum-css/expressvars/`)); } function copyCoreTokens() { return gulp .src(path.join(coreTokensDir, "dist/**/*.css")) .pipe(gulp.dest(`${destination}/tokens/`)); } exports.buildUnique = buildUnique; exports.copyVars = gulp.parallel( buildUnique, copyVars, copyExpressVars, copyCoreTokens );