From f97f4070d50af3a5226eef9259aa20f0c4c25a0b Mon Sep 17 00:00:00 2001 From: Jon Uhlmann Date: Wed, 20 Nov 2024 17:27:24 +0100 Subject: [PATCH] Breaking: Rename purge option to content --- Lib/helper.mjs | 78 ++++++++++++++++++++++++----------- NPM/Makefile | 9 ++++ NPM/dist/module.cjs | 4 -- NPM/dist/module.mjs | 4 +- NPM/package.json | 30 +++++--------- Readme.md | 21 +++++++--- RootFiles/Global/package.json | 2 +- content.mjs | 47 ++------------------- defaults.yaml | 8 ++-- purge.js | 45 -------------------- showConfig.mjs | 15 ++++--- 11 files changed, 110 insertions(+), 153 deletions(-) create mode 100644 NPM/Makefile delete mode 100644 NPM/dist/module.cjs delete mode 100644 purge.js diff --git a/Lib/helper.mjs b/Lib/helper.mjs index c211843..21fdcd6 100644 --- a/Lib/helper.mjs +++ b/Lib/helper.mjs @@ -5,15 +5,14 @@ import { execSync } from "child_process"; const scriptFiles = []; const styleFiles = {}; -const configFile = argv("configFile") || "pipeline.yaml"; -const pipeline = readYamlFile(configFile); -const defaults = readYamlFile("defaults.yaml", "Build/Carbon.Pipeline"); -const config = getConfig(defaults, pipeline); - const watch = argv("watch") === true; const production = argv("production") === true; const minify = production || argv("minify") === true; const silent = argv("silent") === true; + +const configFile = argv("configFile") || "pipeline.yaml"; +const config = getConfig(configFile); + let compression = false; if (production && (!watch || argv("compression") === true)) { compression = config.buildDefaults.compression; @@ -110,21 +109,6 @@ toArray(config.packages).forEach((entry) => { } }); -function getConfig(defaults, pipeline) { - let config = deepmerge(defaults, pipeline); - if (!pipeline.import) { - return config; - } - const imports = typeof pipeline.import == "string" ? [pipeline.import] : pipeline.import; - for (const key in imports) { - const filePath = imports[key]; - if (filePath) { - config = deepmerge(config, readYamlFile(filePath)); - } - } - return config; -} - function argv(key) { // Return true if the key exists and a value is defined if (process.argv.includes(`--${key}`)) { @@ -292,12 +276,11 @@ function convertJsonForDefine(json, prefix) { return define; } -function readYamlFile(file, folder) { - const filePath = folder ? path.join(folder, file) : file; +function readYamlFile(filePath) { try { return yaml.load(fs.readFileSync(path.join("./", filePath), "utf8")); } catch (err) { - error(`Error reading ${file}:`, err); + error(`Error reading ${filePath}:`, err); process.exit(1); } } @@ -330,9 +313,14 @@ function print() { } } +function isObject(item) { + return Object.prototype.toString.call(item) === '[object Object]' +} + function toArray(entry) { if (Array.isArray(entry)) { - return entry.filter((item) => !!item); + // Remove empty and double values + return [...new Set(entry.filter((item) => !!item))]; } if (entry) { return [entry]; @@ -410,7 +398,49 @@ function equalArrays(a, b) { return a.every((value, index) => value === b[index]); } +function getConfig(configFile) { + const defaultConfig = readYamlFile("Build/Carbon.Pipeline/defaults.yaml"); + const pipelineConfig = readYamlFile(configFile); + if (!pipelineConfig.import) { + return mergeConfig(defaultConfig, pipelineConfig); + } + const imports = typeof pipelineConfig.import == "string" ? [pipelineConfig.import] : pipelineConfig.import; + delete pipelineConfig.import; + let importedConfig = []; + for (const key in imports) { + const filePath = imports[key]; + if (filePath) { + importedConfig.push(readYamlFile(filePath)); + } + } + return mergeConfig(defaultConfig, pipelineConfig, ...importedConfig); +} + +function mergeConfig() { + const config = deepmerge(...arguments); + const settings = config?.buildDefaults?.content + if (!settings) { + return config; + } + // Convert object or string to array with unique items + const contentOptions = toArray(isObject(settings) ? Object.values(settings) : settings); + const allowed = []; + const forbidden = []; + // Sort items into allowed and forbidden + contentOptions.forEach((option) => { + if (option.startsWith("!")) { + forbidden.push(option); + return; + } + allowed.push(option); + }); + config.buildDefaults.content = [...allowed, ...forbidden]; + return config; +} + + export { + argv, asyncForEach, scriptFiles, styleFiles, diff --git a/NPM/Makefile b/NPM/Makefile new file mode 100644 index 0000000..4a7e7b0 --- /dev/null +++ b/NPM/Makefile @@ -0,0 +1,9 @@ +.PHONY: upgrade release + +upgrade: + COREPACK_ENABLE_AUTO_PIN=0 pnpm upgrade --latest + COREPACK_ENABLE_AUTO_PIN=0 pnpm up --latest --interactive + +release: + rm -rf node_modules + COREPACK_ENABLE_AUTO_PIN=0 pnpm publish --access public --no-git-checks diff --git a/NPM/dist/module.cjs b/NPM/dist/module.cjs deleted file mode 100644 index dce1a5a..0000000 --- a/NPM/dist/module.cjs +++ /dev/null @@ -1,4 +0,0 @@ -const yaml = require("js-yaml"); -const { red, bold, dim, cyan, magenta } = require("nanocolors"); - -module.exports = { yaml, red, bold, dim, cyan, magenta }; diff --git a/NPM/dist/module.mjs b/NPM/dist/module.mjs index 3b59ed7..dd23094 100644 --- a/NPM/dist/module.mjs +++ b/NPM/dist/module.mjs @@ -1,6 +1,6 @@ import BROWSERLIST from "browserslist"; import chokidar from "chokidar"; -import deepmerge from "deepmerge"; +import { merge } from "ts-deepmerge"; import fs from "fs-extra"; import { glob } from "glob"; import postcssrc from "postcss-load-config"; @@ -11,6 +11,8 @@ import yaml from "js-yaml"; import { DepGraph } from "dependency-graph"; import { red, bold, dim, cyan, magenta } from "nanocolors"; +const deepmerge = merge; + export { BROWSERLIST, chokidar, diff --git a/NPM/package.json b/NPM/package.json index da7cac0..fd6946d 100644 --- a/NPM/package.json +++ b/NPM/package.json @@ -1,20 +1,12 @@ { "name": "carbon-pipeline", - "version": "0.1.6", + "version": "0.2.1", "description": "Exteneral dependencies for Carbon.Pipeline", - "main": "dist/module.cjs", - "module": "dist/module.mjs", - "exports": { - ".": { - "require": "./dist/module.cjs", - "import": "./dist/module.mjs" - } - }, + "main": "dist/module.mjs", "files": [ "dist" ], "scripts": { - "build": "pnpm publish --access public --no-git-checks", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -42,20 +34,20 @@ }, "homepage": "https://github.com/CarbonPackages/Carbon.Pipeline#readme", "dependencies": { - "browserslist": "^4.22.1", - "chokidar": "^3.5.3", - "deepmerge": "^4.3.1", - "dependency-graph": "^0.11.0", - "fs-extra": "^11.1.1", - "glob": "^10.3.10", + "browserslist": "^4.24.2", + "chokidar": "^4.0.1", + "dependency-graph": "^1.0.0", + "fs-extra": "^11.2.0", + "glob": "^11.0.0", "js-yaml": "^4.1.0", "nanocolors": "^0.2.13", - "postcss-load-config": "^4.0.1", + "postcss-load-config": "^6.0.1", "prettyjson": "^1.2.5", "read-cache": "^1.0.0", - "resolve": "^1.22.8" + "resolve": "^1.22.8", + "ts-deepmerge": "^7.0.1" }, "peerDependencies": { - "postcss": "^8.0.0" + "postcss": "^8.4.0" } } diff --git a/Readme.md b/Readme.md index 5d29b79..a4cb56a 100644 --- a/Readme.md +++ b/Readme.md @@ -375,15 +375,25 @@ Of course, you can add your own or remove not-needed Plugins as you want. This i ### Tailwind CSS -This setup comes with [Tailwind CSS], a highly customizable, low-level CSS framework. An example configuration is provided in [`tailwind.config.mjs`]. The setup for purging the CSS files is also configured. [Read more about controlling the file size here][tailwind file-size]. Because the CSS bundling is done with the Javascript API from PostCSS, the [Just-in-Time Mode] from Tailwind CSS works perfectly. To remove a specific package, you could use this pattern in your `pipeline.yaml`: +This setup comes with [Tailwind CSS], a highly customizable, low-level CSS framework. An example configuration is provided in [`tailwind.config.mjs`]. The setup for get the content for the CSS files is also configured. [Read more about controlling the file size here][optimizing-for-production]. To remove a specific package, you could use this pattern in your `pipeline.yaml`: ```yaml buildDefaults: - purge: - - DistributionPackages/**/(Private|NodeTypes)/**/*.{fusion,html,js,jsx,ts,tsx,mjs,mjsx,mts,mtsx,cjs,cjsx,cts,ctsx,svelte,vue} - - "!DistributionPackages/Package.ToRemove" + content: + RemovePacakge: "!DistributionPackages/Package.ToRemove" ``` +By default, following entries are pre-defined: + +```yaml +buildDefaults: + content: + DistributionPackages: DistributionPackages/**/(Private|NodeTypes)/**/*.{fusion,html,js,jsx,ts,tsx,mjs,mjsx,mts,mtsx,cjs,cjsx,cts,ctsx,svelte,vue} + ignoreNodeModules: '!DistributionPackages/**/Private/**/node_modules' +``` + +The script put automatically all entries starting with an `!` at the end of the list. You can control this setting by calling `pnpm showConfig --path=buildDefaults.content` + By the way: [Alpine.js] is excellent in combination with [Tailwind CSS]. ## Javascript @@ -783,10 +793,9 @@ To start Browsersync you can run `browser-sync start --config bs-config.js`. If [`eslint.config.mjs`]: RootFiles/JavaScript/eslint.config.mjs [`.postcssrc.mjs`]: RootFiles/Global/.postcssrc.mjs [tailwind css]: https://tailwindcss.com -[just-in-time mode]: https://tailwindcss.com/docs/just-in-time-mode [alpine.js]: https://github.com/alpinejs/alpine [`tailwind.config.mjs`]: RootFiles/Global/tailwind.config.mjs -[tailwind file-size]: https://tailwindcss.com/docs/controlling-file-size +[optimizing-for-production]: https://tailwindcss.com/docs/optimizing-for-production [sass]: https://sass-lang.com [`sass`]: https://www.npmjs.com/package/sass [`node-sass-tilde-importer`]: https://www.npmjs.com/package/node-sass-tilde-importer diff --git a/RootFiles/Global/package.json b/RootFiles/Global/package.json index 4e48145..8e5a252 100644 --- a/RootFiles/Global/package.json +++ b/RootFiles/Global/package.json @@ -15,7 +15,7 @@ }, "devDependencies": { "autoprefixer": "^10.4.20", - "carbon-pipeline": "^0.1.6", + "carbon-pipeline": "^0.2.1", "concurrently": "^9.0.0", "cssnano": "^7.0.6", "esbuild": "^0.24.0", diff --git a/content.mjs b/content.mjs index 4494d44..cf0e071 100644 --- a/content.mjs +++ b/content.mjs @@ -1,45 +1,4 @@ -import path from "path"; -import fs from "fs"; -import { yaml, red } from "carbon-pipeline"; +import { config } from "./Lib/helper.mjs"; -const configFile = argv("configFile") || "pipeline.yaml"; -let purge = readPurgePath(configFile); -if (!purge) { - purge = readPurgePath("defaults.yaml", "Build/Carbon.Pipeline"); -} - -if (!Array.isArray(purge)) { - purge = [purge]; -} - -function readPurgePath(file, folder) { - const filePath = folder ? path.join(folder, file) : file; - try { - const definition = yaml.load(fs.readFileSync(path.join("./", filePath), "utf8")); - return definition?.buildDefaults?.purge; - } catch (err) { - const linebreak = () => console.log("\n"); - linebreak(); - console.error(red(`Error reading ${file}:`)); - console.error(err); - linebreak(); - process.exit(1); - } -} - -function argv(key) { - // Return true if the key exists and a value is defined - if (process.argv.includes(`--${key}`)) { - return true; - } - const value = process.argv.find((element) => element.startsWith(`--${key}=`)); - - // Return null if the key does not exist and a value is not defined - if (!value) { - return null; - } - - return value.replace(`--${key}=`, ""); -} - -export default purge; +const content = config.buildDefaults.content; +export default content; diff --git a/defaults.yaml b/defaults.yaml index fe6c74f..cf3d8ec 100644 --- a/defaults.yaml +++ b/defaults.yaml @@ -48,10 +48,10 @@ buildDefaults: # external can be a string or an array # https://esbuild.github.io/api/#external external: null - # purge can be a string or an array - purge: - - DistributionPackages/**/(Private|NodeTypes)/**/*.{fusion,html,js,jsx,ts,tsx,mjs,mjsx,mts,mtsx,cjs,cjsx,cts,ctsx,svelte,vue} - - '!DistributionPackages/**/Private/**/node_modules' + + content: + DistributionPackages: DistributionPackages/**/(Private|NodeTypes)/**/*.{fusion,html,js,jsx,ts,tsx,mjs,mjsx,mts,mtsx,cjs,cjsx,cts,ctsx,svelte,vue} + ignoreNodeModules: '!DistributionPackages/**/Private/**/node_modules' compression: brotli: 11 diff --git a/purge.js b/purge.js deleted file mode 100644 index c88c3f8..0000000 --- a/purge.js +++ /dev/null @@ -1,45 +0,0 @@ -const path = require("path"); -const fs = require("fs"); -const { yaml, red } = require("carbon-pipeline"); - -const configFile = argv("configFile") || "pipeline.yaml"; -let purge = readPurgePath(configFile); -if (!purge) { - purge = readPurgePath("defaults.yaml", "Build/Carbon.Pipeline"); -} - -if (!Array.isArray(purge)) { - purge = [purge]; -} - -function readPurgePath(file, folder) { - const filePath = folder ? path.join(folder, file) : file; - try { - const definition = yaml.load(fs.readFileSync(path.join("./", filePath), "utf8")); - return definition?.buildDefaults?.purge; - } catch (err) { - const linebreak = () => console.log("\n"); - linebreak(); - console.error(red(`Error reading ${file}:`)); - console.error(err); - linebreak(); - process.exit(1); - } -} - -function argv(key) { - // Return true if the key exists and a value is defined - if (process.argv.includes(`--${key}`)) { - return true; - } - const value = process.argv.find((element) => element.startsWith(`--${key}=`)); - - // Return null if the key does not exist and a value is not defined - if (!value) { - return null; - } - - return value.replace(`--${key}=`, ""); -} - -module.exports = purge; diff --git a/showConfig.mjs b/showConfig.mjs index 43cf3b6..1e58645 100644 --- a/showConfig.mjs +++ b/showConfig.mjs @@ -1,7 +1,8 @@ -import { config } from "./Lib/helper.mjs"; +import { config, argv } from "./Lib/helper.mjs"; import { prettyjson } from "carbon-pipeline"; -const light = process.argv.includes("--light"); +const light = argv("light"); +const path = argv("path"); const options = { keysColor: light ? "blue" : "yellow", @@ -9,9 +10,13 @@ const options = { stringColor: light ? "black" : "white", numberColor: light ? "magenta" : "brightMagenta", multilineStringColor: light ? "black" : "white", - inlineArrays: true, + inlineArrays: false, }; -const dump = prettyjson.render(config, options); - +let output = config; +if (path) { + const parts = path.split("."); + output = parts.reduce((o, part) => o[part], output); +} +const dump = prettyjson.render(output, options); console.log(`\n\n${dump}\n\n`);