diff --git a/build/build-modules-js/css-versioning.es6.js b/build/build-modules-js/css-versioning.es6.js index 3cf7b9ac4672e..9377ca485fed4 100644 --- a/build/build-modules-js/css-versioning.es6.js +++ b/build/build-modules-js/css-versioning.es6.js @@ -1,30 +1,52 @@ -const { readFile, writeFile } = require('fs/promises'); -const { existsSync, readFileSync } = require('fs'); -const { resolve, dirname } = require('path'); -const crypto = require('crypto'); -const jetpack = require('fs-jetpack'); -const Postcss = require('postcss'); -const UrlVersion = require('postcss-url-version'); +const { createHash } = require('node:crypto'); +const { readdir, readFile, writeFile } = require('fs/promises'); +const { existsSync, readFileSync } = require('node:fs'); +const { dirname, extname, resolve } = require('node:path'); +const { transform, composeVisitors } = require('lightningcss'); const { Timer } = require('./utils/timer.es6.js'); -const opts = { - version: (imagePath, sourceCssPath) => { - if (!sourceCssPath) { - return (new Date()).valueOf().toString(); - } +const skipExternal = true; +const variable = 'v'; - const directory = dirname(sourceCssPath); - if (!(imagePath.startsWith('http') || imagePath.startsWith('//')) && existsSync(resolve(`${directory}/${imagePath}`))) { - const fileBuffer = readFileSync(resolve(`${directory}/${imagePath}`)); - const hashSum = crypto.createHash('md5'); - hashSum.update(fileBuffer); +function version(urlString, fromFile) { + // Skip external URLs + if (skipExternal && (urlString.startsWith('http') || urlString.startsWith('//'))) { + return `${urlString}`; + } + // Skip base64 URLs + if (urlString.startsWith('data:')) { + return `${urlString}`; + } + // Skip URLs with existing query + if (urlString.includes('?')) { + return `${urlString}`; + } - return (hashSum.digest('hex')).substring(0, 6); - } + if (fromFile && existsSync(resolve(`${dirname(fromFile)}/${urlString}`))) { + const hash = createHash('md5'); + hash.update(readFileSync(resolve(`${dirname(fromFile)}/${urlString}`))); - return (new Date()).valueOf().toString(); - }, -}; + return `${urlString}?${variable}=${hash.digest('hex').substring(0, 6)}`; + } + + return `${urlString}?${variable}=${(new Date()).valueOf().toString().substring(0, 6)}`; +} + +/** + * @param {from: String} - the filepath for the css file + * @returns {import('lightningcss').Visitor} - A visitor that replaces the url + */ +function urlVersioning(fromFile) { + return { + /** + * @param {import('lightningcss').Url} url - The url object to transform + * @returns {import('lightningcss').Url} - The transformed url object + */ + Url(url) { + return { ...url, ...{ url: version(url.url, fromFile) } }; + }, + }; +} /** * Adds a hash to the url() parts of the static css @@ -34,9 +56,13 @@ const opts = { */ const fixVersion = async (file) => { try { - const cssString = await readFile(file, { encoding: 'utf8' }); - const data = await Postcss([UrlVersion(opts)]).process(cssString, { from: file }); - await writeFile(file, data.css, { encoding: 'utf8', mode: 0o644 }); + const cssString = await readFile(file); + const { code } = transform({ + code: cssString, + minify: false, + visitor: composeVisitors([urlVersioning(file)]), + }); + await writeFile(file, code, { encoding: 'utf8', mode: 0o644 }); } catch (error) { throw new Error(error); } @@ -50,8 +76,10 @@ const fixVersion = async (file) => { module.exports.cssVersioning = async () => { const bench = new Timer('Versioning'); - const cssFiles = jetpack.find('media', { matching: '/**/**/*.css' }); - await Promise.all(cssFiles.map((file) => fixVersion(file))); + const cssFiles = (await readdir('media', { withFileTypes: true, recursive: true })) + .filter((file) => (!file.isDirectory() && extname(file.name) === '.css')) + .map((file) => `${file.path}/${file.name}`); - bench.stop(); + Promise.all(cssFiles.map((file) => fixVersion(file))) + .then(() => bench.stop()); }; diff --git a/package-lock.json b/package-lock.json index 5f85f0ed86522..8aa14cf518e93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,15 +82,12 @@ "eslint-plugin-import": "^2.28.1", "eslint-plugin-vue": "^8.7.1", "fs-extra": "^10.1.0", - "fs-jetpack": "^5.1.0", "ini": "^2.0.0", "jasmine-core": "^3.99.1", "joomla-cypress": "^0.0.16", "lightningcss": "^1.22.1", "mysql": "^2.18.1", - "postcss": "^8.4.30", "postcss-scss": "^4.0.8", - "postcss-url-version": "^1.0.4", "postgres": "^3.3.5", "recursive-readdir": "^2.2.3", "rimraf": "^3.0.2", @@ -5217,36 +5214,6 @@ "node": ">=12" } }, - "node_modules/fs-jetpack": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/fs-jetpack/-/fs-jetpack-5.1.0.tgz", - "integrity": "sha512-Xn4fDhLydXkuzepZVsr02jakLlmoARPy+YWIclo4kh0GyNGUHnTqeH/w/qIsVn50dFxtp8otPL2t/HcPJBbxUA==", - "dev": true, - "dependencies": { - "minimatch": "^5.1.0" - } - }, - "node_modules/fs-jetpack/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/fs-jetpack/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7695,9 +7662,9 @@ } }, "node_modules/postcss-scss": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.8.tgz", - "integrity": "sha512-Cr0X8Eu7xMhE96PJck6ses/uVVXDtE5ghUTKNUYgm8ozgP2TkgV3LWs3WgLV1xaSSLq8ZFiXaUrj0LVgG1fGEA==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", "dev": true, "funding": [ { @@ -7742,12 +7709,6 @@ "postcss": "^8.3.9" } }, - "node_modules/postcss-url-version": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/postcss-url-version/-/postcss-url-version-1.0.4.tgz", - "integrity": "sha512-ZG60T+XQEXdepCJwKna4a/CtoUVoiwgd7qZYOxWBBygGwAjV7Rg/P9mWr5uaIuReVjtfrGGwz1F4s9Rc/NN8qg==", - "dev": true - }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", diff --git a/package.json b/package.json index 09b42ffac5672..145b65a3e14f3 100644 --- a/package.json +++ b/package.json @@ -108,15 +108,12 @@ "eslint-plugin-import": "^2.28.1", "eslint-plugin-vue": "^8.7.1", "fs-extra": "^10.1.0", - "fs-jetpack": "^5.1.0", "ini": "^2.0.0", "jasmine-core": "^3.99.1", "joomla-cypress": "^0.0.16", "lightningcss": "^1.22.1", "mysql": "^2.18.1", - "postcss": "^8.4.30", "postcss-scss": "^4.0.8", - "postcss-url-version": "^1.0.4", "postgres": "^3.3.5", "recursive-readdir": "^2.2.3", "rimraf": "^3.0.2", @@ -131,4 +128,4 @@ "stylelint-order": "^5.0.0", "stylelint-scss": "^4.7.0" } -} \ No newline at end of file +}