From b7ae2ce96e54f7ec6ff35dfd02e82d7ebfd4f45f Mon Sep 17 00:00:00 2001 From: Matthew RONCHETTO Date: Sun, 26 Jan 2025 12:15:39 -0800 Subject: [PATCH] chore: partial revert of 11f35eed37c437fc32ecc692acbb84e620e6cd4a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removes esbuild system (may™ return in future) - Moves SASS back to src/static/css/ (rather than src/css/) - Re-adds PostCSS, Gulp tasks for SASS transpilation --- gulpfile.ts | 49 +++++++++++- package-lock.json | 111 ++++++++++++++++++++++++++- package.json | 3 +- postcss.config.js | 27 +++++++ src/build/build.ts | 124 ------------------------------- src/build/scss.ts | 45 ----------- src/{ => static}/css/base.scss | 0 src/{ => static}/css/custom.scss | 0 src/{ => static}/css/info.scss | 0 src/{ => static}/css/inter.scss | 0 10 files changed, 187 insertions(+), 172 deletions(-) create mode 100644 postcss.config.js delete mode 100644 src/build/build.ts delete mode 100644 src/build/scss.ts rename src/{ => static}/css/base.scss (100%) rename src/{ => static}/css/custom.scss (100%) rename src/{ => static}/css/info.scss (100%) rename src/{ => static}/css/inter.scss (100%) diff --git a/gulpfile.ts b/gulpfile.ts index cb920cfe..7b83d660 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -14,6 +14,7 @@ import { } from "./src/build/utils"; const gulp = require("gulp"); +const postcss = require("gulp-postcss"); const fs = require("node:fs"); const path = require("node:path"); const through = require("through2"); @@ -22,7 +23,7 @@ const rubric: RubricQuestion[] = loadRubric(); const contributors: Contributor[] = loadContributors(); const products: Product[] = loadProducts(rubric, contributors); -gulp.task("clean", () => { +gulp.task("clean", async () => { return fs.rmSync(path.join(__dirname, "dist"), { recursive: true, force: true, @@ -94,11 +95,57 @@ gulp.task( ) ); +gulp.task("collect dependencies", () => { + return gulp + .src(["./node_modules/lunr/lunr.min.js"]) + .pipe(gulp.dest("./dist/static/deps/")); +}); + +gulp.task("collect static", () => { + return gulp + .src([ + "./src/static/**/*", + "./node_modules/@fortawesome/fontawesome-free/**/*.{woff2,woff}", + "!./src/static/**/*.{css,scss}", + ]) + .pipe(gulp.dest("./dist/static/")); +}); + +gulp.task("collect root favicon", () => { + return gulp.src(["./src/static/img/*.ico"]).pipe(gulp.dest("./dist/")); +}); + +gulp.task("collect product icons", () => { + return gulp.src(["./icons/**/*"]).pipe(gulp.dest("./dist/static/icons/")); +}); + +gulp.task("build css", async () => { + return gulp + .src(["./src/static/css/base.scss"]) + .pipe(postcss()) + .pipe(through.obj((file, _, cb) => { // change to .css extension + if (file.isBuffer()) { + const fp = path.format({ + dir: path.dirname(file.path), + name: path.basename(file.path, ".scss"), + ext: '.css' + }) + } + cb(null, file); + })) + .pipe(gulp.dest("./dist/static/css/")); +}); + gulp.task( "default", gulp.series([ "clean", "build pages", + "collect dependencies", + "collect static", + "collect product icons", + "collect root favicon", + "build css" ]) ); diff --git a/package-lock.json b/package-lock.json index bbeea210..b620fe52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "autoprefixer": "^10.4.20", "gulp": "^5.0.0", "gulp-hb": "^8.0.0", + "gulp-postcss": "^10.0.0", "hbl-arrays": "^0.1.2", "hbl-cmark": "^0.1.2", "hbl-comparison": "^0.1.4", @@ -29,7 +30,7 @@ "postcss-import": "^16.1.0", "postcss-scss": "^4.0.9", "simple-git": "^3.27.0", - "tailwindcss": "^2.1.2", + "tailwindcss": "^2.2.19", "through2": "^4.0.2", "ts-node": "^10.9.2", "typescript": "^5.7.3" @@ -4899,6 +4900,15 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5611,6 +5621,18 @@ "node": ">=0.10.0" } }, + "node_modules/fancy-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", + "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", + "license": "MIT", + "dependencies": { + "color-support": "^1.1.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -6271,6 +6293,36 @@ "readable-stream": "2 || 3" } }, + "node_modules/gulp-postcss": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-10.0.0.tgz", + "integrity": "sha512-z1RF2RJEX/BvFsKN11PXai8lRmihZTiHnlJf7Zu8uHaA/Q7Om4IeN8z1NtMAW5OiLwUY02H0DIFl9tHl0CNSgA==", + "license": "MIT", + "dependencies": { + "fancy-log": "^2.0.0", + "plugin-error": "^2.0.1", + "postcss-load-config": "^5.0.0", + "vinyl-sourcemaps-apply": "^0.2.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/gulp-postcss/node_modules/plugin-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-2.0.1.tgz", + "integrity": "sha512-zMakqvIDyY40xHOvzXka0kUvf40nYIuwRE8dWhti2WtjQZ31xAgBZBhxsK7vK3QbRXS1Xms/LO7B5cuAsfB2Gg==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/gulplog": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", @@ -9645,6 +9697,45 @@ "url": "https://opencollective.com/postcss/" } }, + "node_modules/postcss-load-config": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-5.1.0.tgz", + "integrity": "sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1", + "yaml": "^2.4.2" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + } + } + }, "node_modules/postcss-nested": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", @@ -11568,6 +11659,24 @@ "node": ">=10.13.0" } }, + "node_modules/vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", + "license": "ISC", + "dependencies": { + "source-map": "^0.5.1" + } + }, + "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", diff --git a/package.json b/package.json index df2d2a40..a656a111 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "autoprefixer": "^10.4.20", "gulp": "^5.0.0", "gulp-hb": "^8.0.0", + "gulp-postcss": "^10.0.0", "hbl-arrays": "^0.1.2", "hbl-cmark": "^0.1.2", "hbl-comparison": "^0.1.4", @@ -27,7 +28,7 @@ "postcss-import": "^16.1.0", "postcss-scss": "^4.0.9", "simple-git": "^3.27.0", - "tailwindcss": "^2.1.2", + "tailwindcss": "^2.2.19", "through2": "^4.0.2", "ts-node": "^10.9.2", "typescript": "^5.7.3" diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 00000000..58fb5190 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,27 @@ +const purgecss = require('@fullhuman/postcss-purgecss')({ + // Specify the paths to all of the template files in your project + content: ["./src/**/*.hbs", "./src/**/*.js", "./src/**/*.ts", "./gulpfile.ts"], + + // This is the function used to extract class names from your templates + defaultExtractor: content => { + // Capture as liberally as possible, including things like `h-(screen-1.5)` + const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [] + + // Capture classes within other delimiters like .block(class="w-1/2") in Pug + const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || [] + + return broadMatches.concat(innerMatches) + } +}); + +module.exports = { + plugins: [ + require("postcss-import"), + require("tailwindcss")("tailwind.config.js"), + require("autoprefixer"), + ...process.env.NODE_ENV === 'production' + ? [purgecss] + : [] + ], + syntax: require("postcss-scss") +} diff --git a/src/build/build.ts b/src/build/build.ts deleted file mode 100644 index 530c91fe..00000000 --- a/src/build/build.ts +++ /dev/null @@ -1,124 +0,0 @@ -import esbuild from "esbuild"; -import { build_scss } from "./src/build/scss.ts"; - -import fs from "node:fs"; -import path from "node:path"; - -// get task(s) -if (process.argv.length == 1) { build_all(); } -if (process.argv.length < 2) { process.exit(2); } -const args = process.argv.slice(2); -for (const arg in args) { - switch(arg) { - case "build_api": - clean(); - build_api(); - break; - case "build_pages": - build_directory(); - build_products(); - build_pages(); - build_assets(); - build_scss(); - break; - case "build_assets": - build_assets(); - build_scss(); - break; - case "build": - case "build all": - build_all(); - } -} - -function build_all() { - clean(); - build_directory(); - build_products(); - build_pages(); - build_api(); - build_assets(); - build_scss(); -} - -function clean() { - return await fs.rm(path.join(__dirname, "dist"), { - recursive: true, - force: true - }); -} - -function build_assets() { - [ - "./src/static/**/*", - "./node_modules/@fortawesome/fontawesome-free/**/*.{woff2,woff}", - "./icons/**/*" - ].forEach((pattern) => { - const files = glob(pattern); - files.forEach((file) => { - const tgt = path.join(`${__dirname}/dist/static/`, path.basename(file)); - fs.mkdirSync(`${__dirname}/dist/static/`, { recursive: true }); - fs.copyFileSync(file, tgt); - if (process.env.NODE_ENV === "DEBUG") { console.log(`build_assets(): Copied ${file} to ${tgt}`); } - }); - }); - - [ - './node_modules/lunr/lunr.min.js' - ].forEach((pattern) => { - const files = glob(pattern); - files.forEach((file) => { - const tgt = path.join(`${__dirname}/dist/static/deps/`, path.basename(file)); - fs.mkdirSync(`${__dirname}/dist/static/deps/`, { recursive: true }); - fs.copyFileSync(file, tgt); - if (process.env.NODE_ENV === "DEBUG") { console.log(`build_assets(): Copied ${file} to ${tgt}`); } - }); - }); - - [ - './src/static/img/*.ico' - ].forEach((pattern) => { - const files = glob(pattern); - files.forEach((file) => { - const tgt = path.join(`${__dirname}/dist/static/icons/`, path.basename(file)); - fs.mkdirSync(`${__dirname}/dist/static/icons/`, { recursive: true }); - fs.copyFileSync(file, tgt); - if (process.env.NODE_ENV === "DEBUG") { console.log(`build_assets(): Copied ${file} to ${tgt}`); } - }); - }); - - [ - './src/static/img/*.ico' - ].forEach((pattern) => { - const files = glob(pattern); - files.forEach((file) => { - const tgt = path.join(`${__dirname}/dist/static/icons/`, path.basename(file)); - fs.mkdirSync(`${__dirname}/dist/static/icons/`, { recursive: true }); - fs.copyFileSync(file, tgt); - if (process.env.NODE_ENV === "DEBUG") { console.log(`build_assets(): Copied ${file} to ${tgt}`); } - }); - }); -} - - -function glob(pattern: string): string[] { - const files: string[] = []; - const glob = (dir: string) => { - const items = fs.readdirSync(dir, { withFileTypes: true }); - for (const item of items) { - const path = path.join(dir, item.name); - if (item.isDirectory()) { - glob(item); - } else if (match(item.name, pattern.split('/').pop() || '')) { - files.push(items); - } - } - }; - glob(__dirname); - return files; -} -function match(file: string, pattern: string): boolean { - return new RegExp('^' + pattern.split('*'.map(part => { - return part.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&'); - }).join('.*') + '$')).test(file); -} diff --git a/src/build/scss.ts b/src/build/scss.ts deleted file mode 100644 index 0de3f9ac..00000000 --- a/src/build/scss.ts +++ /dev/null @@ -1,45 +0,0 @@ -import esbuild from "esbuild"; -import { sass } from "esbuild-sass-plugin"; -import postcss from "postcss"; -import autoprefixer from "autoprefixer"; -import postcssImport from "postcss-import"; -import postcssScss from "postcss-scss"; -import purgecss from "@fullhuman/postcss-purgecss"; -import tailwind from "tailwindcss"; - -export function build_scss() { - esbuild.build({ - entryPoints: ["./src/css/base.scss"], - outfile: ["./dist/static/css/base.css"], - bundle: true, - plugins: [sass({ - async transform(src, res) { - const { css } = await postcss([ - autoprefixer, - postcssImport, - postcssScss, - purgecss({ - // Specify the paths to all of the template files in your project - content: [ - "./src/**/*.hbs", - "./src/**/*.js", - "./src/**/*.ts", - "./gulpfile.ts" - ], - // This is the function used to extract class names from your templates - defaultExtractor: content => { - // Capture as liberally as possible, including things like `h-(screen-1.5)` - const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [] - // Capture classes within other delimiters like .block(class="w-1/2") in Pug - const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || [] - - return broadMatches.concat(innerMatches) - } - }), - tailwind("tailwind.config.js"), - ]).process(src, {from: undefined}); - return css; - } - })] - }).catch(() => process.exit(1)); -} diff --git a/src/css/base.scss b/src/static/css/base.scss similarity index 100% rename from src/css/base.scss rename to src/static/css/base.scss diff --git a/src/css/custom.scss b/src/static/css/custom.scss similarity index 100% rename from src/css/custom.scss rename to src/static/css/custom.scss diff --git a/src/css/info.scss b/src/static/css/info.scss similarity index 100% rename from src/css/info.scss rename to src/static/css/info.scss diff --git a/src/css/inter.scss b/src/static/css/inter.scss similarity index 100% rename from src/css/inter.scss rename to src/static/css/inter.scss