From c1c8df8916c5ffe79da490a29334539261ef46b0 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 29 May 2023 09:10:30 -0400 Subject: [PATCH 1/3] feat: generate paragon.config.json during npm run build with themeUrls --- .eslintignore | 1 - build-scss.js | 116 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 90 insertions(+), 27 deletions(-) diff --git a/.eslintignore b/.eslintignore index a693875c8a..a1587677ba 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,6 +4,5 @@ node_modules/ www/ icons/ dependent-usage-analyzer/ -build-scss.js component-generator/ example/ diff --git a/build-scss.js b/build-scss.js index 915df45fae..af437bbfdc 100755 --- a/build-scss.js +++ b/build-scss.js @@ -10,6 +10,28 @@ const { pathToFileURL } = require('url'); const path = require('path'); const { program, Option } = require('commander'); +const updateParagonConfig = ({ + isThemeVariant, + paragonConfig, + name, +}) => { + if (isThemeVariant) { + paragonConfig.themeUrls.variants = { + ...paragonConfig.themeUrls.variants, + [name]: { + default: `./${name}.css`, + minified: `./${name}.min.css`, + }, + }; + } else { + paragonConfig.themeUrls[name] = { + default: `./${name}.css`, + minified: `./${name}.min.css`, + }; + } + return paragonConfig; +}; + /** * Compiles SCSS file with sass and transforms resulting file with PostCSS: * 1. Resulting CSS file @@ -17,40 +39,69 @@ const { program, Option } = require('commander'); * 3. Minified version of resulting CSS file * * @param {string} name - base name of the resulting files - * @param {string} path - path to the SCSS stylesheet + * @param {string} stylesPath - path to the stylesheet to be compiled * @param {string} outDir - indicates where to output compiled files + * @param {boolean} isThemeVariant - indicates whether the stylesheet is a theme variant */ -const compileAndWriteStyleSheets = (name, path, outDir) => { - const compiledStyleSheet = sass.compile(path, { +const compileAndWriteStyleSheets = ({ + name, + stylesPath, + outDir, + isThemeVariant = false, +}) => { + const compiledStyleSheet = sass.compile(stylesPath, { importers: [{ // An importer that redirects relative URLs starting with '~' to 'node_modules'. findFileUrl(url) { if (!url.startsWith('~')) { return null; } - return new URL(url.substring(1), `${pathToFileURL('node_modules')}/node_modules`) - } - }] + return new URL(url.substring(1), `${pathToFileURL('node_modules')}/node_modules`); + }, + }], }); + const commonPostCssPlugins = [ + postCSSCustomMedia({ preserve: true }), + postCSSImport(), + combineSelectors({ removeDuplicatedProperties: true }), + ]; - postCSS([ - postCSSCustomMedia({ preserve: true }), - postCSSImport(), - combineSelectors({ removeDuplicatedProperties: true })]) - .process(compiledStyleSheet.css, { from: path, map: { inline: false } }) + postCSS(commonPostCssPlugins) + .process(compiledStyleSheet.css, { from: stylesPath, map: { inline: false } }) .then(result => { fs.writeFileSync(`${outDir}/${name}.css`, result.css); fs.writeFileSync(`${outDir}/${name}.css.map`, result.map.toString()); + + const hasExistingParagonConfig = fs.existsSync(`${outDir}/paragon.config.json`); + let paragonConfig; + if (!hasExistingParagonConfig) { + const initialConfigOutput = { themeUrls: {} }; + paragonConfig = updateParagonConfig({ + isThemeVariant, + paragonConfig: initialConfigOutput, + name, + }); + } else { + const existingParagonConfigRaw = fs.readFileSync(`${outDir}/paragon.config.json`, 'utf8'); + const existingParagonConfig = JSON.parse(existingParagonConfigRaw); + paragonConfig = updateParagonConfig({ + isThemeVariant, + paragonConfig: existingParagonConfig, + name, + }); + } + fs.writeFileSync(`${outDir}/paragon.config.json`, `${JSON.stringify(paragonConfig, null, 2)}\n`); }); postCSS([ - postCSSCustomMedia({ preserve: true }), - postCSSImport(), - postCSSMinify(), - combineSelectors({ removeDuplicatedProperties: true })]) - .process(compiledStyleSheet.css, { from: path }) - .then(result => fs.writeFileSync(`${outDir}/${name}.min.css`, result.css)); -} + ...commonPostCssPlugins, + postCSSMinify(), + ]) + .process(compiledStyleSheet.css, { from: stylesPath, map: { inline: false } }) + .then(result => { + fs.writeFileSync(`${outDir}/${name}.min.css`, result.css); + }); +}; program .version('0.0.1') @@ -58,7 +109,8 @@ program .addOption( new Option( '--corePath ', - 'Path to the theme\'s core SCSS file, defaults to Paragon\'s core.scss.') + 'Path to the theme\'s core SCSS file, defaults to Paragon\'s core.scss.', + ), ) .addOption( new Option( @@ -79,24 +131,36 @@ program where index.css has imported all other CSS files in the theme's subdirectory. The script will output light.css, dark.css and some_other_custom_theme.css files (together with maps and minified versions). You can provide any amount of themes. Default to paragon's themes. - ` - )) + `, + ), + ) .addOption( new Option( '--outDir ', - 'Specifies directory where to out resulting CSS files.' - ) + 'Specifies directory where to out resulting CSS files.', + ), ) .action(async (options) => { const { corePath = path.resolve(__dirname, 'styles/scss/core/core.scss'), themesPath = path.resolve(__dirname, 'styles/css/themes'), - outDir = './dist' + outDir = './dist', } = options; - compileAndWriteStyleSheets('core', corePath, outDir); + compileAndWriteStyleSheets({ + name: 'core', + stylesPath: corePath, + outDir, + }); fs.readdirSync(themesPath, { withFileTypes: true }) .filter((item) => item.isDirectory()) - .forEach((themeDir) => compileAndWriteStyleSheets(themeDir.name, `${themesPath}/${themeDir.name}/index.css`, outDir)) + .forEach((themeDir) => { + compileAndWriteStyleSheets({ + name: themeDir.name, + stylesPath: `${themesPath}/${themeDir.name}/index.css`, + outDir, + isThemeVariant: true, + }); + }); }); program.parse(process.argv); From 8a58199330cfb6de9680a2b5c2de75bd8b535366 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 29 May 2023 11:55:25 -0400 Subject: [PATCH 2/3] fix: rename to paragon-theme.json --- build-scss.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build-scss.js b/build-scss.js index af437bbfdc..8d453d8f02 100755 --- a/build-scss.js +++ b/build-scss.js @@ -10,6 +10,8 @@ const { pathToFileURL } = require('url'); const path = require('path'); const { program, Option } = require('commander'); +const paragonThemeOutputFilename = 'paragon-theme.json'; + const updateParagonConfig = ({ isThemeVariant, paragonConfig, @@ -72,7 +74,7 @@ const compileAndWriteStyleSheets = ({ fs.writeFileSync(`${outDir}/${name}.css`, result.css); fs.writeFileSync(`${outDir}/${name}.css.map`, result.map.toString()); - const hasExistingParagonConfig = fs.existsSync(`${outDir}/paragon.config.json`); + const hasExistingParagonConfig = fs.existsSync(`${outDir}/${paragonThemeOutputFilename}`); let paragonConfig; if (!hasExistingParagonConfig) { const initialConfigOutput = { themeUrls: {} }; @@ -82,7 +84,7 @@ const compileAndWriteStyleSheets = ({ name, }); } else { - const existingParagonConfigRaw = fs.readFileSync(`${outDir}/paragon.config.json`, 'utf8'); + const existingParagonConfigRaw = fs.readFileSync(`${outDir}/${paragonThemeOutputFilename}`, 'utf8'); const existingParagonConfig = JSON.parse(existingParagonConfigRaw); paragonConfig = updateParagonConfig({ isThemeVariant, @@ -90,7 +92,7 @@ const compileAndWriteStyleSheets = ({ name, }); } - fs.writeFileSync(`${outDir}/paragon.config.json`, `${JSON.stringify(paragonConfig, null, 2)}\n`); + fs.writeFileSync(`${outDir}/${paragonThemeOutputFilename}`, `${JSON.stringify(paragonConfig, null, 2)}\n`); }); postCSS([ From 20b90b6a633c5c0822bc23382d8d06fc59684f13 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 29 May 2023 12:09:41 -0400 Subject: [PATCH 3/3] chore: rename paragonConfig --- build-scss.js | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/build-scss.js b/build-scss.js index 8d453d8f02..a49d591158 100755 --- a/build-scss.js +++ b/build-scss.js @@ -12,26 +12,37 @@ const { program, Option } = require('commander'); const paragonThemeOutputFilename = 'paragon-theme.json'; -const updateParagonConfig = ({ - isThemeVariant, - paragonConfig, +/** + * Updates `paragonThemeOutput` object with appropriate name and URLs. + * + * @param {object} args + * @param {object} args.paragonThemeOutput Object containing the `themeUrls` pointing + * to the core and theme variant CSS files. + * @param {string} args.name Name of the theme variant. + * @param {boolean} args.isThemeVariant Indicates whether the stylesheet is a theme variant. + * + * @returns Updated paragonThemeOutput object. + */ +const updateParagonThemeOutput = ({ + paragonThemeOutput, name, + isThemeVariant, }) => { if (isThemeVariant) { - paragonConfig.themeUrls.variants = { - ...paragonConfig.themeUrls.variants, + paragonThemeOutput.themeUrls.variants = { + ...paragonThemeOutput.themeUrls.variants, [name]: { default: `./${name}.css`, minified: `./${name}.min.css`, }, }; } else { - paragonConfig.themeUrls[name] = { + paragonThemeOutput.themeUrls[name] = { default: `./${name}.css`, minified: `./${name}.min.css`, }; } - return paragonConfig; + return paragonThemeOutput; }; /** @@ -74,25 +85,24 @@ const compileAndWriteStyleSheets = ({ fs.writeFileSync(`${outDir}/${name}.css`, result.css); fs.writeFileSync(`${outDir}/${name}.css.map`, result.map.toString()); - const hasExistingParagonConfig = fs.existsSync(`${outDir}/${paragonThemeOutputFilename}`); - let paragonConfig; - if (!hasExistingParagonConfig) { + const hasExistingParagonThemeOutput = fs.existsSync(`${outDir}/${paragonThemeOutputFilename}`); + let paragonThemeOutput; + if (!hasExistingParagonThemeOutput) { const initialConfigOutput = { themeUrls: {} }; - paragonConfig = updateParagonConfig({ - isThemeVariant, - paragonConfig: initialConfigOutput, + paragonThemeOutput = updateParagonThemeOutput({ + paragonThemeOutput: initialConfigOutput, name, + isThemeVariant, }); } else { - const existingParagonConfigRaw = fs.readFileSync(`${outDir}/${paragonThemeOutputFilename}`, 'utf8'); - const existingParagonConfig = JSON.parse(existingParagonConfigRaw); - paragonConfig = updateParagonConfig({ - isThemeVariant, - paragonConfig: existingParagonConfig, + const existingParagonThemeOutput = JSON.parse(fs.readFileSync(`${outDir}/${paragonThemeOutputFilename}`, 'utf8')); + paragonThemeOutput = updateParagonThemeOutput({ + paragonThemeOutput: existingParagonThemeOutput, name, + isThemeVariant, }); } - fs.writeFileSync(`${outDir}/${paragonThemeOutputFilename}`, `${JSON.stringify(paragonConfig, null, 2)}\n`); + fs.writeFileSync(`${outDir}/${paragonThemeOutputFilename}`, `${JSON.stringify(paragonThemeOutput, null, 2)}\n`); }); postCSS([