diff --git a/.editorconfig b/.editorconfig index dd23145c6f0a0..25870290ad5bf 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,6 +15,6 @@ insert_final_newline = true indent_style = space indent_size = 4 -[*.{js,json,scss,css,yml,vue}] +[*.{mjs,js,json,scss,css,yml,vue}] indent_style = space indent_size = 2 diff --git a/build/.eslintrc b/build/.eslintrc index 1be12f13c4f0d..8e5966c91067f 100644 --- a/build/.eslintrc +++ b/build/.eslintrc @@ -27,7 +27,18 @@ // Disable no-params-reassign for properties "no-param-reassign": ["error", { "props": false }], // Allow usage of dev-dependencies in js files in build directory - "import/no-extraneous-dependencies": ["error", {"devDependencies": ["build/**/*.js"]}], + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": + [ + "build/**/*.js", + "build/**/*.mjs", + "cypress.config.dist.mjs", + "**/**/cypress.config.mjs" + ] + } + ], // Allow strict mode (we are not dealing with modules) "strict": [0], // Disable alert rule till we have a CE in place @@ -46,6 +57,7 @@ ], // Allow extensions on imports "import/extensions": 0, + "import/prefer-default-export": 0, "func-names": [ "error", "as-needed" diff --git a/build/build-modules-js/compilecss.es6.js b/build/build-modules-js/compilecss.mjs similarity index 88% rename from build/build-modules-js/compilecss.es6.js rename to build/build-modules-js/compilecss.mjs index 6e7d3458a97cb..0b55c6a93562a 100644 --- a/build/build-modules-js/compilecss.es6.js +++ b/build/build-modules-js/compilecss.mjs @@ -1,9 +1,12 @@ -const { stat } = require('fs-extra'); -const { sep } = require('path'); -const recursive = require('recursive-readdir'); -const { handleScssFile } = require('./stylesheets/handle-scss.es6.js'); -const { handleCssFile } = require('./stylesheets/handle-css.es6.js'); +import { sep } from 'node:path'; +import recursive from 'recursive-readdir'; +import pkg from 'fs-extra'; + +import { handleScssFile } from './stylesheets/handle-scss.mjs'; +import { handleCssFile } from './stylesheets/handle-css.mjs'; + +const { stat } = pkg; const RootPath = process.cwd(); /** @@ -19,7 +22,7 @@ const RootPath = process.cwd(); * @param {object} options The options * @param {string} path The folder that needs to be compiled, optional */ -module.exports.stylesheets = async (options, path) => { +export const stylesheets = async (options, path) => { const files = []; let folders = []; diff --git a/build/build-modules-js/compilejs.es6.js b/build/build-modules-js/compilejs.mjs similarity index 78% rename from build/build-modules-js/compilejs.es6.js rename to build/build-modules-js/compilejs.mjs index e837d5d0a21a9..53d68b96b75cd 100644 --- a/build/build-modules-js/compilejs.es6.js +++ b/build/build-modules-js/compilejs.mjs @@ -1,8 +1,10 @@ -const { stat } = require('fs-extra'); -const { sep } = require('path'); -const recursive = require('recursive-readdir'); -const { handleES5File } = require('./javascript/handle-es5.es6.js'); -const { handleESMFile } = require('./javascript/compile-to-es2017.es6.js'); +import { stat } from 'node:fs/promises'; +import { sep } from 'node:path'; + +import recursive from 'recursive-readdir'; + +import { handleES5File } from './javascript/handle-es5.mjs'; +import { handleESMFile } from './javascript/compile-to-es2017.mjs'; const RootPath = process.cwd(); @@ -21,7 +23,7 @@ const RootPath = process.cwd(); * @param { string } path The folder that needs to be compiled, optional * @param { string } mode esm for ES2017, es5 for ES5, both for both */ -module.exports.scripts = async (options, path) => { +export const scripts = async (options, path) => { const files = []; let folders = []; @@ -49,7 +51,7 @@ module.exports.scripts = async (options, path) => { // Loop to get the files that should be compiled via parameter // eslint-disable-next-line no-restricted-syntax for (const folder of folders) { - folderPromises.push(recursive(folder, ['!*.+(js)'])); + folderPromises.push(recursive(folder, ['!*.+(m|js)'])); } const computedFiles = await Promise.all(folderPromises); @@ -63,9 +65,9 @@ module.exports.scripts = async (options, path) => { return; } - if (file.match(/\.es5\.js$/)) { + if (file.endsWith('.es5.js')) { jsFilesPromises.push(handleES5File(file)); - } else if (file.match(/\.es6\.js$/) || file.match(/\.w-c\.es6\.js$/)) { + } else if ((file.endsWith('.es6.js') || file.endsWith('.w-c.es6.js')) && !file.startsWith('_')) { esmFilesPromises.push(handleESMFile(file)); } }); diff --git a/build/build-modules-js/compress.es6.js b/build/build-modules-js/compress.mjs similarity index 72% rename from build/build-modules-js/compress.es6.js rename to build/build-modules-js/compress.mjs index e8a2b4c9adf55..99cd2b41fb01b 100644 --- a/build/build-modules-js/compress.es6.js +++ b/build/build-modules-js/compress.mjs @@ -1,7 +1,8 @@ -const { readdir } = require('fs').promises; -const { extname } = require('path'); -const { compressFile } = require('./utils/compressFile.es6.js'); -const { Timer } = require('./utils/timer.es6.js'); +import { readdir } from 'node:fs/promises'; +import { extname } from 'node:path'; + +import { compressFile } from './utils/compressFile.mjs'; +import { Timer } from './utils/timer.mjs'; /** * Get files recursively @@ -11,7 +12,7 @@ const { Timer } = require('./utils/timer.es6.js'); async function getFiles(path) { // Get files within the current directory return (await readdir(path, { withFileTypes: true, recursive: true })) - .filter((file) => (!file.isDirectory() && ['.js', '.css'].includes(extname(file.name)))) + .filter((file) => !file.isDirectory() && ['.js', '.css'].includes(extname(file.name))) .map((file) => `${file.path}/${file.name}`); } @@ -19,7 +20,7 @@ async function getFiles(path) { * Method that will pre compress (gzip) all .css/.js files * in the templates and in the media folder */ -module.exports.compressFiles = async (enableBrotli = false) => { +export const compressFiles = async (enableBrotli = false) => { const bench = new Timer('Gzip'); const paths = [ `${process.cwd()}/media`, diff --git a/build/build-modules-js/css-versioning.es6.js b/build/build-modules-js/css-versioning.mjs similarity index 85% rename from build/build-modules-js/css-versioning.es6.js rename to build/build-modules-js/css-versioning.mjs index e9775325ce019..5188b67fa856e 100644 --- a/build/build-modules-js/css-versioning.es6.js +++ b/build/build-modules-js/css-versioning.mjs @@ -1,9 +1,9 @@ -const { createHash } = require('node:crypto'); -const { readdir, readFile, writeFile } = require('node: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'); +import { createHash } from 'node:crypto'; +import { readdir, readFile, writeFile } from 'node:fs/promises'; +import { existsSync, readFileSync } from 'node:fs'; +import { dirname, extname, resolve } from 'node:path'; +import { transform, composeVisitors } from 'lightningcss'; +import { Timer } from './utils/timer.mjs'; const RootPath = process.cwd(); const skipExternal = true; @@ -76,7 +76,7 @@ const fixVersion = async (file) => { * * @returns {Promise} */ -module.exports.cssVersioning = async () => { +export const cssVersioning = async () => { const bench = new Timer('Versioning'); const cssFiles = (await readdir(`${RootPath}/media`, { withFileTypes: true, recursive: true })) diff --git a/build/build-modules-js/error-pages.es6.js b/build/build-modules-js/error-pages.mjs similarity index 94% rename from build/build-modules-js/error-pages.es6.js rename to build/build-modules-js/error-pages.mjs index 840cd73542af8..4f5be1df61ce4 100644 --- a/build/build-modules-js/error-pages.es6.js +++ b/build/build-modules-js/error-pages.mjs @@ -1,11 +1,12 @@ -const { +import { access, mkdir, readFile, writeFile, -} = require('fs').promises; -const Ini = require('ini'); -const { dirname } = require('path'); -const Recurs = require('recursive-readdir'); -const { transform } = require('esbuild'); -const LightningCSS = require('lightningcss'); +} from 'node:fs/promises'; +import { dirname } from 'node:path'; + +import Ini from 'ini'; +import Recurs from 'recursive-readdir'; +import { transform } from 'esbuild'; +import { transform as transformCss } from 'lightningcss'; const RootPath = process.cwd(); const dir = `${RootPath}/installation/language`; @@ -21,7 +22,7 @@ const srcPath = `${RootPath}/build/warning_page`; * And also specific strings in the languages in the installation folder! * Also the base strings are held in build/build-modules-js/settings.json */ -module.exports.createErrorPages = async (options) => { +export const createErrorPages = async (options) => { const iniFilesProcess = []; const processPages = []; global.incompleteObj = {}; @@ -33,7 +34,7 @@ module.exports.createErrorPages = async (options) => { let cssContent = await readFile(`${srcPath}/template.css`, { encoding: 'utf8' }); let jsContent = await readFile(`${srcPath}/template.js`, { encoding: 'utf8' }); - const { code } = LightningCSS.transform({ + const { code } = transformCss({ code: Buffer.from(cssContent), minify: true, }); diff --git a/build/build-modules-js/init/cleanup-media.es6.js b/build/build-modules-js/init/cleanup-media.mjs similarity index 84% rename from build/build-modules-js/init/cleanup-media.es6.js rename to build/build-modules-js/init/cleanup-media.mjs index 76f741892b3a0..cf30316d100b7 100644 --- a/build/build-modules-js/init/cleanup-media.es6.js +++ b/build/build-modules-js/init/cleanup-media.mjs @@ -1,9 +1,11 @@ -const { - stat, mkdir, copy, remove, -} = require('fs-extra'); -const { join } = require('path'); +import { join } from 'node:path'; + +import pkg from 'fs-extra'; const RootPath = process.cwd(); +const { + stat, mkdir, copy, remove, +} = pkg; /** * Method that will erase the media/vendor folder @@ -11,7 +13,7 @@ const RootPath = process.cwd(); * * @returns {Promise} */ -module.exports.cleanVendors = async () => { +export const cleanVendors = async () => { if (process.env.SKIP_COMPOSER_CHECK === 'YES') { await mkdir('media/vendor/debugbar', { recursive: true, mode: 0o755 }); // eslint-disable-next-line no-console @@ -39,7 +41,7 @@ module.exports.cleanVendors = async () => { await remove(join(RootPath, 'media/vendor/debugbar/vendor/jquery')); } else { // eslint-disable-next-line no-console - console.error('You need to run `npm install` AFTER the command `composer install`!!!. The debug plugin HASN\'T installed all its front end assets'); + console.error("You need to run `npm install` AFTER the command `composer install`!!!. The debug plugin HASN'T installed all its front end assets"); process.exitCode = 1; } }; diff --git a/build/build-modules-js/init/common/concat-files.es6.js b/build/build-modules-js/init/common/concat-files.mjs similarity index 83% rename from build/build-modules-js/init/common/concat-files.es6.js rename to build/build-modules-js/init/common/concat-files.mjs index 071cfff298fc6..b76b3bc46d8c2 100644 --- a/build/build-modules-js/init/common/concat-files.es6.js +++ b/build/build-modules-js/init/common/concat-files.mjs @@ -1,4 +1,4 @@ -const { readFile, writeFile, existsSync } = require('fs-extra'); +import { readFile, writeFile, existsSync } from 'fs-extra'; const RootPath = process.cwd(); @@ -10,7 +10,7 @@ const RootPath = process.cwd(); * * @returns {void} */ -module.exports.concatFiles = async (files, output) => { +export const concatFiles = async (files, output) => { const promises = []; // eslint-disable-next-line no-restricted-syntax diff --git a/build/build-modules-js/init/common/copy-all-files.es6.js b/build/build-modules-js/init/common/copy-all-files.mjs similarity index 80% rename from build/build-modules-js/init/common/copy-all-files.es6.js rename to build/build-modules-js/init/common/copy-all-files.mjs index 9802a382ca406..3037ec32d5cc7 100644 --- a/build/build-modules-js/init/common/copy-all-files.es6.js +++ b/build/build-modules-js/init/common/copy-all-files.mjs @@ -1,5 +1,6 @@ -const { copy } = require('fs-extra'); -const { join } = require('path'); +import { join } from 'node:path'; + +import { copy } from 'fs-extra'; const RootPath = process.cwd(); @@ -12,7 +13,7 @@ const RootPath = process.cwd(); * * @returns { void } */ -module.exports.copyAllFiles = async (dirName, name, type) => { +export const copyAllFiles = async (dirName, name, type) => { const folderName = dirName === '/' ? '/' : `/${dirName}`; await copy( join(RootPath, `node_modules/${name}/${folderName}`), diff --git a/build/build-modules-js/init/common/resolve-package.es6.js b/build/build-modules-js/init/common/resolve-package.cjs similarity index 95% rename from build/build-modules-js/init/common/resolve-package.es6.js rename to build/build-modules-js/init/common/resolve-package.cjs index c69e25e5cef3e..00305806691bb 100644 --- a/build/build-modules-js/init/common/resolve-package.es6.js +++ b/build/build-modules-js/init/common/resolve-package.cjs @@ -1,4 +1,4 @@ -const { existsSync, readdirSync } = require('fs-extra'); +const { existsSync, readdirSync } = require('node:fs'); /** * Find full path for package file. diff --git a/build/build-modules-js/init/exemptions/tinymce.es6.js b/build/build-modules-js/init/exemptions/tinymce.mjs similarity index 86% rename from build/build-modules-js/init/exemptions/tinymce.es6.js rename to build/build-modules-js/init/exemptions/tinymce.mjs index 232976e910e46..f781a66239c03 100644 --- a/build/build-modules-js/init/exemptions/tinymce.es6.js +++ b/build/build-modules-js/init/exemptions/tinymce.mjs @@ -1,11 +1,12 @@ -const { - existsSync, copy, readFile, writeFile, mkdir, removeSync, -} = require('fs-extra'); +import { existsSync } from 'node:fs'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; -const { join } = require('path'); +import pkg from 'fs-extra'; -const { copyAllFiles } = require('../common/copy-all-files.es6.js'); +import { copyAllFiles } from '../common/copy-all-files.mjs'; +const { copy, removeSync } = pkg; const RootPath = process.cwd(); const xmlVersionStr = /()(.+)(<\/version>)/; @@ -36,10 +37,10 @@ const copyArrayFiles = async (dirName, files, name, type) => { /** * tinyMCE needs special treatment */ -module.exports.tinyMCE = async (packageName, version) => { +export const tinyMCE = async (packageName, version) => { const itemvendorPath = join(RootPath, `media/vendor/${packageName}`); - if (!await existsSync(itemvendorPath)) { + if (!(await existsSync(itemvendorPath))) { await mkdir(itemvendorPath, { mode: 0o755 }); await mkdir(join(itemvendorPath, 'icons'), { mode: 0o755 }); await mkdir(join(itemvendorPath, 'plugins'), { mode: 0o755 }); @@ -65,7 +66,10 @@ module.exports.tinyMCE = async (packageName, version) => { // Remove that sourcemap... let tinyWrongMap = await readFile(`${RootPath}/media/vendor/tinymce/skins/ui/oxide/skin.min.css`, { encoding: 'utf8' }); - tinyWrongMap = tinyWrongMap.replace('/*# sourceMappingURL=skin.min.css.map */', ''); + tinyWrongMap = tinyWrongMap.replace( + '/*# sourceMappingURL=skin.min.css.map */', + '', + ); await writeFile(`${RootPath}/media/vendor/tinymce/skins/ui/oxide/skin.min.css`, tinyWrongMap, { encoding: 'utf8', mode: 0o644 }); // Restore our code on the vendor folders diff --git a/build/build-modules-js/init/localise-packages.es6.js b/build/build-modules-js/init/localise-packages.mjs similarity index 82% rename from build/build-modules-js/init/localise-packages.es6.js rename to build/build-modules-js/init/localise-packages.mjs index e72229a3a52e1..c4c3e3b7aca13 100644 --- a/build/build-modules-js/init/localise-packages.es6.js +++ b/build/build-modules-js/init/localise-packages.mjs @@ -1,9 +1,16 @@ +import { dirname, join } from 'node:path'; +import { createRequire } from 'node:module'; +import { existsSync } from 'node:fs'; + +import pkg from 'fs-extra'; + +import { tinyMCE } from './exemptions/tinymce.mjs'; +import { resolvePackageFile } from './common/resolve-package.cjs'; + +const require = createRequire(import.meta.url); const { - existsSync, copy, writeFile, mkdir, mkdirs, ensureDir, -} = require('fs-extra'); -const { dirname, join } = require('path'); -const { tinyMCE } = require('./exemptions/tinymce.es6.js'); -const { resolvePackageFile } = require('./common/resolve-package.es6.js'); + copy, mkdirs, mkdir, ensureDir, writeFile, +} = pkg; const RootPath = process.cwd(); @@ -54,16 +61,13 @@ const resolvePackage = async (vendor, packageName, mediaVendorPath, options, reg ['js', 'css', 'filesExtra'].forEach((type) => { if (!vendor[type]) return; - promises.push( - copyFilesTo(vendor[type], modulePathRoot, join(mediaVendorPath, vendorName), type), - ); + promises.push(copyFilesTo(vendor[type], modulePathRoot, join(mediaVendorPath, vendorName), type)); }); } // Copy the license if existsSync if (options.settings.vendors[packageName].licenseFilename - && await existsSync(`${join(RootPath, `node_modules/${packageName}`)}/${options.settings.vendors[packageName].licenseFilename}`) - ) { + && (await existsSync(`${join(RootPath, `node_modules/${packageName}`)}/${options.settings.vendors[packageName].licenseFilename}`))) { const dest = join(mediaVendorPath, vendorName); await copy( `${join(RootPath, `node_modules/${packageName}`)}/${options.settings.vendors[packageName].licenseFilename}`, @@ -113,7 +117,7 @@ const resolvePackage = async (vendor, packageName, mediaVendorPath, options, reg * * @returns {Promise} */ -module.exports.localisePackages = async (options) => { +export const localisePackages = async (options) => { const mediaVendorPath = join(RootPath, 'media/vendor'); const registry = { $schema: 'https://developer.joomla.org/schemas/json-schema/web_assets.json', @@ -125,7 +129,7 @@ module.exports.localisePackages = async (options) => { }; const promises = []; - if (!await existsSync(mediaVendorPath)) { + if (!(await existsSync(mediaVendorPath))) { await mkdir(mediaVendorPath, { recursive: true, mode: 0o755 }); } @@ -140,9 +144,5 @@ module.exports.localisePackages = async (options) => { await Promise.all(promises); // Write assets registry - await writeFile( - join(mediaVendorPath, 'joomla.asset.json'), - JSON.stringify(registry, null, 2), - { encoding: 'utf8', mode: 0o644 }, - ); + await writeFile(join(mediaVendorPath, 'joomla.asset.json'), JSON.stringify(registry, null, 2), { encoding: 'utf8', mode: 0o644 }); }; diff --git a/build/build-modules-js/init/minify-vendor.es6.js b/build/build-modules-js/init/minify-vendor.mjs similarity index 83% rename from build/build-modules-js/init/minify-vendor.es6.js rename to build/build-modules-js/init/minify-vendor.mjs index fff1782f63160..25541a21ceb65 100644 --- a/build/build-modules-js/init/minify-vendor.es6.js +++ b/build/build-modules-js/init/minify-vendor.mjs @@ -1,7 +1,8 @@ -const { lstat, readFile, writeFile } = require('fs-extra'); -const { sep, basename } = require('path'); -const recursive = require('recursive-readdir'); -const { transform } = require('esbuild'); +import { sep, basename } from 'node:path'; +import { lstat, readFile, writeFile } from 'node:fs/promises'; + +import recursive from 'recursive-readdir'; +import { transform } from 'esbuild'; const RootPath = process.cwd(); @@ -19,10 +20,7 @@ const folders = [ let allFiles = []; -const noMinified = [ - 'accessibility.min.js', - 'short-and-sweet.min.js', -]; +const noMinified = ['accessibility.min.js', 'short-and-sweet.min.js']; const alreadyMinified = [ 'media/vendor/webcomponentsjs/js/webcomponents-bundle.js', @@ -65,8 +63,8 @@ const minifyJS = async (file) => { } const content = await readFile(file, { encoding: 'utf8' }); - const isMinified = alreadyMinified.includes(file.replace(`${RootPath}${sep}`, '')); + if (isMinified || needsDotJS) { minified = content; } else { @@ -75,11 +73,7 @@ const minifyJS = async (file) => { const newFile = needsDotJS ? file.replace('.min.js', '.js') : file.replace('.js', '.min.js'); // Write the file - await writeFile( - newFile, - minified, - { encoding: 'utf8', mode: 0o644 }, - ); + await writeFile(newFile, minified, { encoding: 'utf8', mode: 0o644 }); }; /** @@ -87,7 +81,7 @@ const minifyJS = async (file) => { * * @returns {Promise} */ -module.exports.minifyVendor = async () => { +export const minifyVendor = async () => { const folderPromises = []; const filesPromises = []; diff --git a/build/build-modules-js/init/patches.es6.js b/build/build-modules-js/init/patches.mjs similarity index 87% rename from build/build-modules-js/init/patches.es6.js rename to build/build-modules-js/init/patches.mjs index 3cea4ff76cf6e..3a5bcc06f6459 100644 --- a/build/build-modules-js/init/patches.es6.js +++ b/build/build-modules-js/init/patches.mjs @@ -1,5 +1,5 @@ -const { readFile, writeFile } = require('fs-extra'); -const { join } = require('path'); +import { join } from 'node:path'; +import { readFile, writeFile } from 'node:fs/promises'; const RootPath = process.cwd(); @@ -10,7 +10,7 @@ const RootPath = process.cwd(); * * @returns {Promise} */ -module.exports.patchPackages = async (options) => { +export const patchPackages = async (options) => { const mediaVendorPath = join(RootPath, 'media/vendor'); // Joomla's hack to expose the chosen base classes so we can extend it ourselves @@ -18,9 +18,12 @@ module.exports.patchPackages = async (options) => { let dest = join(mediaVendorPath, 'chosen'); const chosenPath = `${dest}/${options.settings.vendors['chosen-js'].js['chosen.jquery.js']}`; let ChosenJs = await readFile(chosenPath, { encoding: 'utf8' }); - ChosenJs = ChosenJs.replace('}).call(this);', ` document.AbstractChosen = AbstractChosen; + ChosenJs = ChosenJs.replace( + '}).call(this);', + ` document.AbstractChosen = AbstractChosen; document.Chosen = Chosen; -}).call(this);`); +}).call(this);`, + ); await writeFile(chosenPath, ChosenJs, { encoding: 'utf8', mode: 0o644 }); // Append initialising code to the end of the Short-and-Sweet javascript diff --git a/build/build-modules-js/init/recreate-media.es6.js b/build/build-modules-js/init/recreate-media.mjs similarity index 89% rename from build/build-modules-js/init/recreate-media.es6.js rename to build/build-modules-js/init/recreate-media.mjs index a0f8989421446..9f8fbf002f6f5 100644 --- a/build/build-modules-js/init/recreate-media.es6.js +++ b/build/build-modules-js/init/recreate-media.mjs @@ -1,12 +1,12 @@ -const { - stat, copy, existsSync, emptyDirSync, -} = require('fs-extra'); -const { - readFile, writeFile, readdir, -} = require('fs').promises; -const { join, extname } = require('path'); -const recursive = require('recursive-readdir'); +import { + stat, readFile, writeFile, readdir, +} from 'node:fs/promises'; +import { join, extname } from 'node:path'; +import pkg from 'fs-extra'; +import recursive from 'recursive-readdir'; + +const { copy, existsSync, emptyDirSync } = pkg; const RootPath = process.cwd(); const knownDirs = [ 'templates/site/cassiopeia', @@ -32,7 +32,7 @@ const updateSettings = async (options) => { * * @returns {Promise} */ -module.exports.recreateMediaFolder = async (options) => { +export const recreateMediaFolder = async (options) => { await updateSettings(options); const installedVendors = Object.keys(options.settings.vendors).map((vendor) => { if (vendor === 'choices.js') { diff --git a/build/build-modules-js/javascript/build-bootstrap-js.es6.js b/build/build-modules-js/javascript/build-bootstrap-js.mjs similarity index 70% rename from build/build-modules-js/javascript/build-bootstrap-js.es6.js rename to build/build-modules-js/javascript/build-bootstrap-js.mjs index c52d3d18bd454..02e81becf691e 100644 --- a/build/build-modules-js/javascript/build-bootstrap-js.es6.js +++ b/build/build-modules-js/javascript/build-bootstrap-js.mjs @@ -1,23 +1,36 @@ -const { +import { readdir, readFile, writeFile, unlink, -} = require('fs').promises; -const { resolve } = require('path'); -const { transform } = require('esbuild'); -const rimraf = require('rimraf'); -const rollup = require('rollup'); -const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const replace = require('@rollup/plugin-replace'); -const { babel } = require('@rollup/plugin-babel'); -const bsVersion = require('../../../package.json').dependencies.bootstrap.replace(/^\^|~/, ''); +} from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { transform } from 'esbuild'; +import rimraf from 'rimraf'; +import { rollup } from 'rollup'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import replace from '@rollup/plugin-replace'; +import { babel } from '@rollup/plugin-babel'; +import { createRequire } from 'node:module'; +const require = createRequire(import.meta.url); +const opts = require('../../../package.json'); + +const bsVersion = opts.dependencies.bootstrap.replace(/^\^|~/, ''); const tasks = []; const inputFolder = 'build/media_source/vendor/bootstrap/js'; const outputFolder = 'media/vendor/bootstrap/js'; const createMinified = async (file) => { - const initial = await readFile(resolve(outputFolder, file), { encoding: 'utf8' }); - const mini = await transform(initial.replace('./popper.js', `./popper.min.js?${bsVersion}`).replace('./dom.js', `./dom.min.js?${bsVersion}`), { minify: true }); - await writeFile(resolve(outputFolder, file), initial.replace('./popper.js', `./popper.js?${bsVersion}`).replace('./dom.js', `./dom.js?${bsVersion}`), { encoding: 'utf8', mode: 0o644 }); + const initial = await readFile(resolve(outputFolder, file), { + encoding: 'utf8', + }); + const mini = await transform( + initial.replace('./popper.js', `./popper.min.js?${bsVersion}`).replace('./dom.js', `./dom.min.js?${bsVersion}`), + { minify: true }, + ); + await writeFile( + resolve(outputFolder, file), + initial.replace('./popper.js', `./popper.js?${bsVersion}`).replace('./dom.js', `./dom.js?${bsVersion}`), + { encoding: 'utf8', mode: 0o644 }, + ); await writeFile(resolve(outputFolder, file.replace('.js', '.min.js')), mini.code, { encoding: 'utf8', mode: 0o644 }); }; @@ -28,13 +41,13 @@ const build = async () => { const domImports = await readdir(resolve('node_modules/bootstrap', 'js/src/dom')); const utilImports = await readdir(resolve('node_modules/bootstrap', 'js/src/util')); - const bundle = await rollup.rollup({ + const bundle = await rollup({ input: resolve(inputFolder, 'index.es6.js'), plugins: [ nodeResolve(), replace({ preventAssignment: true, - 'process.env.NODE_ENV': '\'production\'', + 'process.env.NODE_ENV': "'production'", }), babel({ exclude: 'node_modules/core-js/**', @@ -45,10 +58,7 @@ const build = async () => { '@babel/preset-env', { targets: { - browsers: [ - '> 1%', - 'not op_mini all', - ], + browsers: ['> 1%', 'not op_mini all'], }, }, ], @@ -87,7 +97,7 @@ const build = async () => { await bundle.close(); }; -module.exports.bootstrapJs = async () => { +export const bootstrapJs = async () => { rimraf.sync(resolve(outputFolder)); try { diff --git a/build/build-modules-js/javascript/build-codemirror.es6.js b/build/build-modules-js/javascript/build-codemirror.mjs similarity index 82% rename from build/build-modules-js/javascript/build-codemirror.es6.js rename to build/build-modules-js/javascript/build-codemirror.mjs index cac5370e30f74..707ba9ffaea12 100644 --- a/build/build-modules-js/javascript/build-codemirror.es6.js +++ b/build/build-modules-js/javascript/build-codemirror.mjs @@ -3,25 +3,31 @@ */ /* eslint-disable import/no-extraneous-dependencies, global-require, import/no-dynamic-require */ -const { readFileSync, writeFile } = require('fs-extra'); -const cliProgress = require('cli-progress'); -const rollup = require('rollup'); -const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const replace = require('@rollup/plugin-replace'); -const { transform } = require('esbuild'); -const { resolvePackageFile, getPackagesUnderScope } = require('../init/common/resolve-package.es6.js'); +import { readFileSync } from 'node:fs'; +import { writeFile } from 'node:fs/promises'; +import { createRequire } from 'node:module'; + +import cliProgress from 'cli-progress'; +import { rollup } from 'rollup'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import replace from '@rollup/plugin-replace'; +import { transform } from 'esbuild'; + +const require = createRequire(import.meta.url); + +const { + resolvePackageFile, + getPackagesUnderScope, +} = require('../init/common/resolve-package.cjs'); // Build the module const buildModule = async (module, externalModules, destFile) => { - const build = await rollup.rollup({ + const build = await rollup({ input: module, external: externalModules || [], plugins: [ nodeResolve(), - replace({ - preventAssignment: true, - 'process.env.NODE_ENV': '"production"', - }), + replace({ preventAssignment: true, 'process.env.NODE_ENV': '"production"' }), ], }); @@ -76,14 +82,10 @@ const updateAssetRegistry = async (modules, externalModules) => { }); // Write assets registry - await writeFile( - destPath, - JSON.stringify(registry, null, 2), - { encoding: 'utf8', mode: 0o644 }, - ); + await writeFile(destPath, JSON.stringify(registry, null, 2), { encoding: 'utf8', mode: 0o644 }); }; -module.exports.compileCodemirror = async () => { +export const compileCodemirror = async () => { // eslint-disable-next-line no-console console.log('Building Codemirror Components...'); diff --git a/build/build-modules-js/javascript/build-com_media-js.es6.js b/build/build-modules-js/javascript/build-com_media-js.mjs similarity index 82% rename from build/build-modules-js/javascript/build-com_media-js.es6.js rename to build/build-modules-js/javascript/build-com_media-js.mjs index 53cfac168a4f8..ef040701f5483 100644 --- a/build/build-modules-js/javascript/build-com_media-js.es6.js +++ b/build/build-modules-js/javascript/build-com_media-js.mjs @@ -1,22 +1,26 @@ -const { resolve } = require('path'); -const { writeFile, copyFile } = require('fs').promises; -const rollup = require('rollup'); -const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const replace = require('@rollup/plugin-replace'); -const { babel } = require('@rollup/plugin-babel'); -const VuePlugin = require('rollup-plugin-vue'); -const commonjs = require('@rollup/plugin-commonjs'); -const { minifyJsCode } = require('./minify.es6.js'); -require('dotenv').config(); +import { writeFile, copyFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; + +import { rollup, watch } from 'rollup'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import replace from '@rollup/plugin-replace'; +import { babel } from '@rollup/plugin-babel'; +import VuePlugin from 'rollup-plugin-vue'; +import commonjs from '@rollup/plugin-commonjs'; +import dotenv from 'dotenv'; + +import { minifyCode } from './minify.mjs'; + +dotenv.config(); const inputJS = 'administrator/components/com_media/resources/scripts/mediamanager.es6.js'; const isProduction = process.env.NODE_ENV !== 'DEVELOPMENT'; -module.exports.mediaManager = async () => { +export const mediaManager = async () => { // eslint-disable-next-line no-console console.log('Building Media Manager ES Module...'); - const bundle = await rollup.rollup({ + const bundle = await rollup({ input: resolve(inputJS), plugins: [ VuePlugin({ @@ -64,12 +68,13 @@ module.exports.mediaManager = async () => { ], }); - bundle.write({ - format: 'es', - sourcemap: !isProduction ? 'inline' : false, - file: 'media/com_media/js/media-manager.js', - }) - .then((value) => (isProduction ? minifyJsCode(value.output[0].code) : value.output[0])) + bundle + .write({ + format: 'es', + sourcemap: !isProduction ? 'inline' : false, + file: 'media/com_media/js/media-manager.js', + }) + .then((value) => (isProduction ? minifyCode(value.output[0].code) : value.output[0])) .then((content) => { if (isProduction) { // eslint-disable-next-line no-console @@ -89,12 +94,12 @@ module.exports.mediaManager = async () => { await bundle.close(); }; -module.exports.watchMediaManager = async () => { +export const watchMediaManager = async () => { // eslint-disable-next-line no-console console.log('Watching Media Manager js+vue files...'); // eslint-disable-next-line no-console console.log('========='); - const watcher = rollup.watch({ + const watcher = watch({ input: resolve(inputJS), plugins: [ VuePlugin({ diff --git a/build/build-modules-js/javascript/compile-to-es2017.es6.js b/build/build-modules-js/javascript/compile-to-es2017.mjs similarity index 58% rename from build/build-modules-js/javascript/compile-to-es2017.es6.js rename to build/build-modules-js/javascript/compile-to-es2017.mjs index b3c005513adb1..18542f9055515 100644 --- a/build/build-modules-js/javascript/compile-to-es2017.es6.js +++ b/build/build-modules-js/javascript/compile-to-es2017.mjs @@ -1,16 +1,14 @@ /* eslint-disable import/no-extraneous-dependencies, global-require, import/no-dynamic-require */ -const { access, writeFile } = require('fs').promises; -const { constants } = require('fs'); -const { basename, sep, resolve } = require('path'); -const rollup = require('rollup'); -const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const replace = require('@rollup/plugin-replace'); -const { babel } = require('@rollup/plugin-babel'); -const LightningCSS = require('lightningcss'); -const { renderSync } = require('sass-embedded'); -const { minifyJsCode } = require('./minify.es6.js'); -const { getPackagesUnderScope } = require('../init/common/resolve-package.es6.js'); +import { writeFile } from 'node:fs/promises'; +import { basename, sep, resolve } from 'node:path'; + +import { rollup } from 'rollup'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import { babel } from '@rollup/plugin-babel'; + +import { minifyCode } from './minify.mjs'; +import { getPackagesUnderScope } from '../init/common/resolve-package.cjs'; function esmOrIife(file) { if (file.endsWith('core.es6.js') || file.endsWith('validate.es6.js')) { @@ -19,40 +17,6 @@ function esmOrIife(file) { return 'es'; } -const getWcMinifiedCss = async (file) => { - let scssFileExists = false; - const scssFile = file.replace(`${sep}js${sep}`, `${sep}scss${sep}`).replace(/\.w-c\.es6\.js$/, '.scss'); - try { - // eslint-disable-next-line no-bitwise - await access(scssFile, constants.R_OK | constants.W_OK); - - scssFileExists = true; - } catch { /* nothing */ } - - /// {{CSS_CONTENTS_PLACEHOLDER}} - if (scssFileExists) { - let compiled; - try { - compiled = renderSync({ file: scssFile }); - } catch (error) { - // eslint-disable-next-line no-console - console.error(`${error.column} - ${error.message} - ${error.line}`); - } - - if (typeof compiled === 'object' && compiled.css) { - const { code } = LightningCSS.transform({ - code: Buffer.from(compiled.css.toString()), - minify: true, - }); - return code; - } - } - - return ''; -}; - // List of external modules that should not be resolved by rollup const externalModules = []; const collectExternals = () => { @@ -87,22 +51,16 @@ const collectExternals = () => { * * @param file the full path to the file + filename + extension */ -module.exports.handleESMFile = async (file) => { +export const handleESMFile = async (file) => { const newPath = file.replace(/\.w-c\.es6\.js$/, '').replace(/\.es6\.js$/, '').replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`); - const minifiedCss = await getWcMinifiedCss(file); // Make sure externals are collected collectExternals(); - const bundle = await rollup.rollup({ + const bundle = await rollup({ input: resolve(file), plugins: [ nodeResolve({ preferBuiltins: false }), - replace({ - preventAssignment: true, - CSS_CONTENTS_PLACEHOLDER: minifiedCss, - delimiters: ['{{', '}}'], - }), babel({ exclude: 'node_modules/core-js/**', babelHelpers: 'bundled', @@ -137,7 +95,7 @@ module.exports.handleESMFile = async (file) => { sourcemap: false, file: resolve(`${newPath}.js`), }) - .then((value) => minifyJsCode(value.output[0].code)) + .then((value) => minifyCode(value.output[0].code)) .then((content) => { // eslint-disable-next-line no-console console.log(`✅ ES2017 file: ${basename(file).replace('.es6.js', '.js')}: transpiled`); diff --git a/build/build-modules-js/javascript/handle-es5.es6.js b/build/build-modules-js/javascript/handle-es5.es6.js deleted file mode 100644 index a20085bd9b84d..0000000000000 --- a/build/build-modules-js/javascript/handle-es5.es6.js +++ /dev/null @@ -1,16 +0,0 @@ -const FsExtra = require('fs-extra'); -const { basename, dirname, sep } = require('path'); -const { minifyJs } = require('./minify.es6.js'); - -module.exports.handleES5File = async (file) => { - if (file.match(/\.es5\.js$/)) { - // ES5 file, we will copy the file and then minify it in place - // Ensure that the directories exist or create them - await FsExtra.ensureDir(dirname(file).replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`)); - await FsExtra.copy(file, file.replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`).replace('.es5.js', '.js'), { preserveTimestamps: true }); - // eslint-disable-next-line no-console - console.log(`✅ Legacy js file: ${basename(file)}: copied`); - - minifyJs(file.replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`).replace('.es5.js', '.js')); - } -}; diff --git a/build/build-modules-js/javascript/handle-es5.mjs b/build/build-modules-js/javascript/handle-es5.mjs new file mode 100644 index 0000000000000..fbb262b345b4b --- /dev/null +++ b/build/build-modules-js/javascript/handle-es5.mjs @@ -0,0 +1,21 @@ +import { basename, dirname, sep } from 'node:path'; + +import FsExtra from 'fs-extra'; +import { minifyFile } from './minify.mjs'; + +export const handleES5File = async (file) => { + if (file.endsWith('.js')) { + // ES5 file, we will copy the file and then minify it in place + // Ensure that the directories exist or create them + await FsExtra.ensureDir(dirname(file).replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`)); + await FsExtra.copy( + file, + file.replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`).replace('.es5.js', '.js'), + { preserveTimestamps: true }, + ); + // eslint-disable-next-line no-console + console.log(`✅ Legacy js file: ${basename(file)}: copied`); + + minifyFile(file.replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`).replace('.es5.js', '.js')); + } +}; diff --git a/build/build-modules-js/javascript/minify.es6.js b/build/build-modules-js/javascript/minify.mjs similarity index 62% rename from build/build-modules-js/javascript/minify.es6.js rename to build/build-modules-js/javascript/minify.mjs index 11df77e597d66..371c27369034a 100644 --- a/build/build-modules-js/javascript/minify.es6.js +++ b/build/build-modules-js/javascript/minify.mjs @@ -1,13 +1,15 @@ -const { transform } = require('esbuild'); -const { readFile, writeFile } = require('fs-extra'); -const { basename } = require('path'); +import { basename } from 'node:path'; +import { readFile, writeFile } from 'node:fs/promises'; + +import { transform } from 'esbuild'; + /** * Minify a js file using esbuild * * @param file * @returns {Promise} */ -const minifyFile = async (file) => { +export const minifyFile = async (file) => { const fileContent = await readFile(file, { encoding: 'utf8' }); const content = await transform(fileContent, { minify: true }); await writeFile(file.replace('.js', '.min.js'), content.code, { encoding: 'utf8', mode: 0o644 }); @@ -21,7 +23,4 @@ const minifyFile = async (file) => { * @param code * @returns {Promise} */ -const minifyCode = async (code) => transform(code, { minify: true }); - -module.exports.minifyJs = minifyFile; -module.exports.minifyJsCode = minifyCode; +export const minifyCode = async (code) => transform(code, { minify: true }); diff --git a/build/build-modules-js/stylesheets/handle-css.es6.js b/build/build-modules-js/stylesheets/handle-css.mjs similarity index 81% rename from build/build-modules-js/stylesheets/handle-css.es6.js rename to build/build-modules-js/stylesheets/handle-css.mjs index 9c626ad0b8d76..13d463e0e5e14 100644 --- a/build/build-modules-js/stylesheets/handle-css.es6.js +++ b/build/build-modules-js/stylesheets/handle-css.mjs @@ -1,10 +1,13 @@ +import { dirname, sep } from 'node:path'; + +import pkg from 'fs-extra'; +import { transform as transformCss } from 'lightningcss'; + const { copy, readFile, writeFile, ensureDir, -} = require('fs-extra'); -const { dirname, sep } = require('path'); -const LightningCSS = require('lightningcss'); +} = pkg; -module.exports.handleCssFile = async (file) => { +export const handleCssFile = async (file) => { const outputFile = file.replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`); try { // CSS file, we will copy the file and then minify it in place @@ -16,7 +19,7 @@ module.exports.handleCssFile = async (file) => { } const content = await readFile(file, { encoding: 'utf8' }); - const { code } = LightningCSS.transform({ + const { code } = transformCss({ code: Buffer.from(content), minify: true, }); diff --git a/build/build-modules-js/stylesheets/handle-scss.es6.js b/build/build-modules-js/stylesheets/handle-scss.mjs similarity index 58% rename from build/build-modules-js/stylesheets/handle-scss.es6.js rename to build/build-modules-js/stylesheets/handle-scss.mjs index 314f400b39c0c..610a731e8fe82 100644 --- a/build/build-modules-js/stylesheets/handle-scss.es6.js +++ b/build/build-modules-js/stylesheets/handle-scss.mjs @@ -1,12 +1,14 @@ -const rtlcss = require('rtlcss'); -const { writeFile } = require('fs').promises; -const { ensureDir } = require('fs-extra'); -const { dirname, sep } = require('path'); -const LightningCSS = require('lightningcss'); -const Sass = require('sass-embedded'); - -module.exports.handleScssFile = async (file) => { - const cssFile = file.replace(`${sep}scss${sep}`, `${sep}css${sep}`) +import { writeFile } from 'node:fs/promises'; +import { dirname, sep } from 'node:path'; + +import rtlcss from 'rtlcss'; +import { ensureDir } from 'fs-extra'; +import { transform as transformCss, Features } from 'lightningcss'; +import * as Sass from 'sass-embedded'; + +export const handleScssFile = async (file) => { + const cssFile = file + .replace(`${sep}scss${sep}`, `${sep}css${sep}`) .replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`) .replace('.scss', '.css'); @@ -19,7 +21,7 @@ module.exports.handleScssFile = async (file) => { process.exitCode = 1; } - let contents = LightningCSS.transform({ + let contents = transformCss({ code: Buffer.from(compiled.css.toString()), minify: false, }).code; @@ -37,19 +39,15 @@ ${contents}`, { encoding: 'utf8', mode: 0o644 }, ); - const cssMin = LightningCSS.transform({ + const cssMin = transformCss({ code: Buffer.from(contents), minify: true, - exclude: LightningCSS.Features.VendorPrefixes, + exclude: Features.VendorPrefixes, }); // Ensure the folder exists or create it await ensureDir(dirname(cssFile.replace('.css', '.min.css')), {}); - await writeFile( - cssFile.replace('.css', '.min.css'), - `@charset "UTF-8";${cssMin.code}`, - { encoding: 'utf8', mode: 0o644 }, - ); + await writeFile(cssFile.replace('.css', '.min.css'), `@charset "UTF-8";${cssMin.code}`, { encoding: 'utf8', mode: 0o644 }); // eslint-disable-next-line no-console console.log(`✅ SCSS File compiled: ${cssFile}`); diff --git a/build/build-modules-js/stylesheets/scss-transform.es6.js b/build/build-modules-js/stylesheets/scss-transform.mjs similarity index 71% rename from build/build-modules-js/stylesheets/scss-transform.es6.js rename to build/build-modules-js/stylesheets/scss-transform.mjs index 6cb29421016ce..2d1c66e1c88e6 100644 --- a/build/build-modules-js/stylesheets/scss-transform.es6.js +++ b/build/build-modules-js/stylesheets/scss-transform.mjs @@ -1,12 +1,15 @@ -const Fs = require('fs').promises; -const FsExtra = require('fs-extra'); -const { dirname, sep } = require('path'); -const LightningCSS = require('lightningcss'); -const Sass = require('sass-embedded'); - -module.exports.compile = async (file) => { - const cssFile = file.replace(`${sep}scss${sep}`, `${sep}css${sep}`) - .replace('.scss', '.css').replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`); +import Fs from 'node:fs/promises'; +import { dirname, sep } from 'node:path'; + +import FsExtra from 'fs-extra'; +import LightningCSS from 'lightningcss'; +import Sass from 'sass-embedded'; + +export const compile = async (file) => { + const cssFile = file + .replace(`${sep}scss${sep}`, `${sep}css${sep}`) + .replace('.scss', '.css') + .replace(`${sep}build${sep}media_source${sep}`, `${sep}media${sep}`); let compiled; try { diff --git a/build/build-modules-js/utils/compressFile.es6.js b/build/build-modules-js/utils/compressFile.mjs similarity index 78% rename from build/build-modules-js/utils/compressFile.es6.js rename to build/build-modules-js/utils/compressFile.mjs index 8373729eebd95..547284d3d90d1 100644 --- a/build/build-modules-js/utils/compressFile.es6.js +++ b/build/build-modules-js/utils/compressFile.mjs @@ -1,6 +1,6 @@ -const { readFile, writeFile } = require('fs').promises; -const { promisify } = require('util'); -const { constants, gzip, brotliCompress } = require('zlib'); +import { readFile, writeFile } from 'node:fs/promises'; +import { promisify } from 'node:util'; +import { constants, gzip, brotliCompress } from 'node:zlib'; const gzipOpts = { level: constants.Z_BEST_COMPRESSION, @@ -19,7 +19,7 @@ const gzipEncode = (data) => gzipPromise(data, gzipOpts); const brotliPromise = promisify(brotliCompress); const brotliEncode = (data) => brotliPromise(data, brotliOpts); -const compressFile = async (file, enableBrotli) => { +export const compressFile = async (file, enableBrotli) => { if (file.endsWith('.min.js') || file.endsWith('.min.css')) { try { const data = await readFile(file); @@ -35,5 +35,3 @@ const compressFile = async (file, enableBrotli) => { } } }; - -module.exports.compressFile = compressFile; diff --git a/build/build-modules-js/utils/debounce.es6.js b/build/build-modules-js/utils/debounce.mjs similarity index 69% rename from build/build-modules-js/utils/debounce.es6.js rename to build/build-modules-js/utils/debounce.mjs index 26daf161e5afe..5d0aad1d19ce5 100644 --- a/build/build-modules-js/utils/debounce.es6.js +++ b/build/build-modules-js/utils/debounce.mjs @@ -7,4 +7,4 @@ * @param { int } interval The interval */ // eslint-disable-next-line no-param-reassign, no-return-assign, default-param-last -module.exports.debounce = (callback, time = 250, interval) => (...args) => clearTimeout(interval, interval = setTimeout(callback, time, ...args)); +export const debounce = (callback, time = 250, interval) => (...args) => clearTimeout(interval, (interval = setTimeout(callback, time, ...args))); diff --git a/build/build-modules-js/utils/hashfromfile.es6.js b/build/build-modules-js/utils/hashfromfile.es6.js deleted file mode 100644 index 6bc47c03d5485..0000000000000 --- a/build/build-modules-js/utils/hashfromfile.es6.js +++ /dev/null @@ -1,12 +0,0 @@ -const { createHash } = require('crypto'); -const { createReadStream } = require('fs'); - -/** - * Get a hash (MD5) for a given file - * @param filePath - * @returns {Promise} - */ -module.exports.createHashFromFile = (filePath) => new Promise((res) => { - const hash = createHash('md5'); - createReadStream(filePath).on('data', (data) => hash.update(data)).on('end', () => res(hash.digest('hex'))); -}); diff --git a/build/build-modules-js/utils/hashfromfile.mjs b/build/build-modules-js/utils/hashfromfile.mjs new file mode 100644 index 0000000000000..8bbe367e95988 --- /dev/null +++ b/build/build-modules-js/utils/hashfromfile.mjs @@ -0,0 +1,14 @@ +import { createReadStream } from 'node:fs'; +import { createHash } from 'node:crypto'; + +/** + * Get a hash (MD5) for a given file + * @param filePath + * @returns {Promise} + */ +export const createHashFromFile = (filePath) => new Promise((res) => { + const hash = createHash('md5'); + createReadStream(filePath) + .on('data', (data) => hash.update(data)) + .on('end', () => res(hash.digest('hex'))); +}); diff --git a/build/build-modules-js/utils/timer.es6.js b/build/build-modules-js/utils/timer.mjs similarity index 88% rename from build/build-modules-js/utils/timer.es6.js rename to build/build-modules-js/utils/timer.mjs index 011b83c89f47f..eb5b9f1fc89f4 100644 --- a/build/build-modules-js/utils/timer.es6.js +++ b/build/build-modules-js/utils/timer.mjs @@ -4,7 +4,7 @@ * @param name * @returns {{stop: stop}} */ -class Timer { +export class Timer { constructor(name) { this.start = new Date(); this.name = name; @@ -17,5 +17,3 @@ class Timer { console.log('Timer:', this.name, 'finished in', time, 'ms'); } } - -module.exports.Timer = Timer; diff --git a/build/build-modules-js/versioning.es6.js b/build/build-modules-js/versioning.mjs similarity index 92% rename from build/build-modules-js/versioning.es6.js rename to build/build-modules-js/versioning.mjs index 39c5256b6d2c6..3eb985a6abbf5 100644 --- a/build/build-modules-js/versioning.es6.js +++ b/build/build-modules-js/versioning.mjs @@ -1,11 +1,12 @@ -const { +import { lstat, readdir, readFile, writeFile, -} = require('fs-extra'); -const { +} from 'node:fs/promises'; +import { basename, dirname, resolve, sep, -} = require('path'); -const { createHashFromFile } = require('./utils/hashfromfile.es6.js'); -const { Timer } = require('./utils/timer.es6.js'); +} from 'node:path'; + +import { createHashFromFile } from './utils/hashfromfile.mjs'; +import { Timer } from './utils/timer.mjs'; const RootPath = process.cwd(); const exclusion = [ @@ -110,7 +111,7 @@ const fixVersion = async (directory) => { * * @returns {Promise} */ -module.exports.versioning = async () => { +export const versioning = async () => { const bench = new Timer('Versioning'); const tasks = []; let mediaDirectories = await readdir(resolve(RootPath, 'media')); diff --git a/build/build-modules-js/watch.es6.js b/build/build-modules-js/watch.mjs similarity index 63% rename from build/build-modules-js/watch.es6.js rename to build/build-modules-js/watch.mjs index b17de23a34b6d..648dc468a82a8 100644 --- a/build/build-modules-js/watch.es6.js +++ b/build/build-modules-js/watch.mjs @@ -1,21 +1,22 @@ -const chokidar = require('chokidar'); -const { +import { join, extname, basename, dirname, -} = require('path'); -const { handleESMFile } = require('./javascript/compile-to-es2017.es6.js'); -const { handleES5File } = require('./javascript/handle-es5.es6.js'); -const { handleScssFile } = require('./stylesheets/handle-scss.es6.js'); -const { handleCssFile } = require('./stylesheets/handle-css.es6.js'); -const { debounce } = require('./utils/debounce.es6.js'); +} from 'node:path'; +import chokidar from 'chokidar'; + +import { handleESMFile } from './javascript/compile-to-es2017.mjs'; +import { handleES5File } from './javascript/handle-es5.mjs'; +import { handleScssFile } from './stylesheets/handle-scss.mjs'; +import { handleCssFile } from './stylesheets/handle-css.mjs'; +import { debounce } from './utils/debounce.mjs'; const RootPath = process.cwd(); const processFile = (file) => { if (extname(file) === '.js' && !dirname(file).startsWith(join(RootPath, 'build/media_source/vendor/bootstrap/js'))) { - if (file.match(/\.w-c\.es6\.js$/) || file.match(/\.es6\.js$/)) { + if ((file.endsWith('.w-c.es6.js') || file.endsWith('.es6.js')) && !file.startsWith('_')) { debounce(handleESMFile(file), 300); } - if (file.match(/\.es5\.js/)) { + if (file.endsWith('.es5..js')) { debounce(handleES5File(file), 300); } } @@ -28,7 +29,7 @@ const processFile = (file) => { } }; -module.exports.watching = (path) => { +export const watching = (path) => { const watchingPath = path ? join(RootPath, path) : join(RootPath, 'build/media_source'); const watcher = chokidar.watch(watchingPath, { ignored: /(^|[/\\])\../, // ignore dotfiles diff --git a/build/build.js b/build/build.js deleted file mode 100644 index ef76ed7a4e09e..0000000000000 --- a/build/build.js +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Command line helper - * - * To get the complete functional media folder please run: - * npm ci - * - * For dedicated tasks, please run: - * node build.js --build-pages will create the error pages (for incomplete repo build PHP+NPM) - * node build.js --copy-assets will clean the media/vendor folder and then will populate the folder from node_modules - * node build.js --compile-js will transpile ES6 files and also uglify the ES6,ES5 files - * node build.js --compile-css will compile all the scss defined files and also create a minified version of the css - * node build.js --compile-bs will compile all the Bootstrap javascript components - * node build.js --com-media will compile the media manager Vue application - * node build.js --watch-com-media will watch and compile the media manager Vue application - * node build.js --gzip will create gzip files for all the minified stylesheets and scripts. - * node build.js --cssversioning will update all the url entries providing accurate versions for stylesheets. - * node build.js --versioning will update all the joomla.assets.json files providing accurate versions for stylesheets and scripts. - */ - -const { Command } = require('commander'); -const semver = require('semver'); - -// Joomla Build modules -const { createErrorPages } = require('./build-modules-js/error-pages.es6.js'); -const { stylesheets } = require('./build-modules-js/compilecss.es6.js'); -const { scripts } = require('./build-modules-js/compilejs.es6.js'); -const { bootstrapJs } = require('./build-modules-js/javascript/build-bootstrap-js.es6.js'); -const { localisePackages } = require('./build-modules-js/init/localise-packages.es6.js'); -const { minifyVendor } = require('./build-modules-js/init/minify-vendor.es6.js'); -const { patchPackages } = require('./build-modules-js/init/patches.es6.js'); -const { cleanVendors } = require('./build-modules-js/init/cleanup-media.es6.js'); -const { recreateMediaFolder } = require('./build-modules-js/init/recreate-media.es6'); -const { watching } = require('./build-modules-js/watch.es6.js'); -const { mediaManager, watchMediaManager } = require('./build-modules-js/javascript/build-com_media-js.es6'); -const { compressFiles } = require('./build-modules-js/compress.es6.js'); -const { cssVersioning } = require('./build-modules-js/css-versioning.es6.js'); -const { versioning } = require('./build-modules-js/versioning.es6.js'); -const { Timer } = require('./build-modules-js/utils/timer.es6.js'); -const { compileCodemirror } = require('./build-modules-js/javascript/build-codemirror.es6.js'); - -// The settings -const options = require('../package.json'); -const settings = require('./build-modules-js/settings.json'); - - -const handleError = (err, terminateCode) => { - console.error(err); // eslint-disable-line no-console - process.exitCode = terminateCode; -}; - -if (semver.gte(semver.minVersion(options.engines.node), semver.clean(process.version))) { - handleError(`Node version ${semver.clean(process.version)} is not supported, please upgrade to Node version ${semver.clean(options.engines.node)}`, 1); -} - -// The command line -const Program = new Command(); - -// Merge Joomla's specific settings to the main package.json object -if ('settings' in settings) { - options.settings = settings.settings; -} - -const allowedVersion = () => { - if (!semver.satisfies(process.version.substring(1), options.engines.node)) { - handleError(`Command line tools require Node Version ${options.engines.node} but found ${process.version}`, -1); - } -}; - -// Initialize the CLI -Program - .allowUnknownOption() - .version(options.version) - .option('--copy-assets', 'Moving files from node_modules to media folder') - .option('--build-pages', 'Creates the error pages for unsupported PHP version & incomplete environment') - .option('--compile-js, --compile-js path', 'Handles ES6, ES5 and web component scripts') - .option('--compile-css, --compile-css path', 'Compiles all the scss files to css') - .option('--compile-bs', 'Compiles all the Bootstrap component scripts.') - .option('--compile-codemirror', 'Compiles all the codemirror modules.') - .option('--watch', 'Watch file changes and re-compile (ATM only works for the js in the media_source).') - .option('--com-media', 'Compile the Media Manager client side App.') - .option('--watch-com-media', 'Watch and Compile the Media Manager client side App.') - .option('--gzip', 'Compress all the minified stylesheets and scripts.') - .option('--prepare', 'Run all the needed tasks to initialise the repo') - .option('--cssversioning', 'Update all the url() versions on their relative stylesheet files') - .option('--versioning', 'Update all the .js/.css versions on their relative joomla.assets.json') - - .addHelpText('after', ` -Version: ${options.version} -`); - -Program.parse(process.argv); - -const cliOptions = Program.opts(); - -// Update the vendor folder -if (cliOptions.copyAssets) { - allowedVersion(); - recreateMediaFolder(options) - .then(() => cleanVendors()) - .then(() => localisePackages(options)) - .then(() => patchPackages(options)) - .then(() => minifyVendor()) - .catch((error) => handleError(error, 1)); -} - -// Creates the error pages for unsupported PHP version & incomplete environment -if (cliOptions.buildPages) { - createErrorPages(options) - .catch((err) => handleError(err, 1)); -} - -// Convert scss to css -if (cliOptions.compileCss) { - stylesheets(options, Program.args[0]) - .catch((err) => handleError(err, 1)); -} - -// Compress/transpile the javascript files -if (cliOptions.compileJs) { - scripts(options, Program.args[0]) - .catch((err) => handleError(err, 1)); -} - -// Compress/transpile the javascript files -if (cliOptions.watch) { - watching(Program.args[0]); -} - -// Gzip js/css files -if (cliOptions.compileBs) { - bootstrapJs(); -} - -// Compile codemirror -if (cliOptions.compileCodemirror) { - compileCodemirror(); -} - -// Gzip js/css files -if (cliOptions.gzip) { - compressFiles(); -} - -// Compile the media manager -if (cliOptions.comMedia) { - // false indicates "no watch" - mediaManager(false); -} - -// Watch & Compile the media manager -if (cliOptions.watchComMedia) { - watchMediaManager(true); -} - -// Update the .js/.css versions -if (cliOptions.versioning) { - versioning() - .catch((err) => handleError(err, 1)); -} - -// Update the url() versions in the .css files -if (cliOptions.cssversioning) { - cssVersioning() - .catch((err) => handleError(err, 1)); -} - -// Prepare the repo for dev work -if (cliOptions.prepare) { - const bench = new Timer('Build'); - allowedVersion(); - recreateMediaFolder(options) - .then(() => cleanVendors()) - .then(() => localisePackages(options)) - .then(() => patchPackages(options)) - .then(() => minifyVendor()) - .then(() => createErrorPages(options)) - .then(() => stylesheets(options, Program.args[0])) - .then(() => scripts(options, Program.args[0])) - .then(() => mediaManager()) - .then(() => bootstrapJs()) - .then(() => compileCodemirror()) - .then(() => bench.stop('Build')) - .catch((err) => handleError(err, -1)); -} diff --git a/build/build.mjs b/build/build.mjs new file mode 100644 index 0000000000000..c9094d5b968d7 --- /dev/null +++ b/build/build.mjs @@ -0,0 +1,210 @@ +/** + * Command line helper + * + * To get the complete functional media folder please run: + * npm ci + * + * For dedicated tasks, please run: + * node build.mjs --build-pages will create the error pages (for incomplete repo build PHP+NPM) + * node build.mjs --copy-assets will clean the media/vendor folder and then will populate the folder from node_modules + * node build.mjs --compile-js will transpile ES6 files and also uglify the ES6,ES5 files + * node build.mjs --compile-css will compile all the scss defined files and also create a minified version of the css + * node build.mjs --compile-bs will compile all the Bootstrap javascript components + * node build.mjs --com-media will compile the media manager Vue application + * node build.mjs --watch-com-media will watch and compile the media manager Vue application + * node build.mjs --gzip will create gzip files for all the minified stylesheets and scripts. + * node build.mjs --cssversioning will update all the url entries providing accurate versions for stylesheets. + * node build.mjs --versioning will update all the joomla.assets.json files providing accurate versions for stylesheets and scripts. + */ + +import { createRequire } from 'node:module'; +import { Command } from 'commander'; +import semver from 'semver'; + +// Joomla Build modules +import { createErrorPages } from './build-modules-js/error-pages.mjs'; +import { stylesheets } from './build-modules-js/compilecss.mjs'; +import { scripts } from './build-modules-js/compilejs.mjs'; +import { bootstrapJs } from './build-modules-js/javascript/build-bootstrap-js.mjs'; +import { localisePackages } from './build-modules-js/init/localise-packages.mjs'; +import { minifyVendor } from './build-modules-js/init/minify-vendor.mjs'; +import { patchPackages } from './build-modules-js/init/patches.mjs'; +import { cleanVendors } from './build-modules-js/init/cleanup-media.mjs'; +import { recreateMediaFolder } from './build-modules-js/init/recreate-media.mjs'; +import { watching } from './build-modules-js/watch.mjs'; +import { mediaManager, watchMediaManager } from './build-modules-js/javascript/build-com_media-js.mjs'; +import { compressFiles } from './build-modules-js/compress.mjs'; +import { cssVersioning } from './build-modules-js/css-versioning.mjs'; +import { versioning } from './build-modules-js/versioning.mjs'; +import { Timer } from './build-modules-js/utils/timer.mjs'; +import { compileCodemirror } from './build-modules-js/javascript/build-codemirror.mjs'; + +const require = createRequire(import.meta.url); + +// The settings +const options = require('../package.json'); +const settings = require('./build-modules-js/settings.json'); + +const handleError = (err, terminateCode) => { + console.error(err); // eslint-disable-line no-console + process.exitCode = terminateCode; +}; + +if (semver.gte(semver.minVersion(options.engines.node), semver.clean(process.version))) { + handleError( + `Node version ${semver.clean(process.version)} is not supported, please upgrade to Node version ${semver.clean(options.engines.node)}`, + 1, + ); +} + +// The command line +const Program = new Command(); + +// Merge Joomla's specific settings to the main package.json object +if ('settings' in settings) { + options.settings = settings.settings; +} + +const allowedVersion = () => { + if (!semver.satisfies(process.version.substring(1), options.engines.node)) { + handleError( + `Command line tools require Node Version ${options.engines.node} but found ${process.version}`, + -1, + ); + } +}; + +// Initialize the CLI +Program.allowUnknownOption() + .version(options.version) + .option('--copy-assets', 'Moving files from node_modules to media folder') + .option( + '--build-pages', + 'Creates the error pages for unsupported PHP version & incomplete environment', + ) + .option( + '--compile-js, --compile-js path', + 'Handles ES6, ES5 and web component scripts', + ) + .option( + '--compile-css, --compile-css path', + 'Compiles all the scss files to css', + ) + .option('--compile-bs', 'Compiles all the Bootstrap component scripts.') + .option('--compile-codemirror', 'Compiles all the codemirror modules.') + .option( + '--watch', + 'Watch file changes and re-compile (ATM only works for the js in the media_source).', + ) + .option('--com-media', 'Compile the Media Manager client side App.') + .option( + '--watch-com-media', + 'Watch and Compile the Media Manager client side App.', + ) + .option('--gzip', 'Compress all the minified stylesheets and scripts.') + .option('--prepare', 'Run all the needed tasks to initialise the repo') + .option( + '--cssversioning', + 'Update all the url() versions on their relative stylesheet files', + ) + .option( + '--versioning', + 'Update all the .js/.css versions on their relative joomla.assets.json', + ) + + .addHelpText( + 'after', + ` +Version: ${options.version} +`, + ); + +Program.parse(process.argv); + +const cliOptions = Program.opts(); + +// Update the vendor folder +if (cliOptions.copyAssets) { + allowedVersion(); + recreateMediaFolder(options) + .then(() => cleanVendors()) + .then(() => localisePackages(options)) + .then(() => patchPackages(options)) + .then(() => minifyVendor()) + .catch((error) => handleError(error, 1)); +} + +// Creates the error pages for unsupported PHP version & incomplete environment +if (cliOptions.buildPages) { + createErrorPages(options).catch((err) => handleError(err, 1)); +} + +// Convert scss to css +if (cliOptions.compileCss) { + stylesheets(options, Program.args[0]).catch((err) => handleError(err, 1)); +} + +// Compress/transpile the javascript files +if (cliOptions.compileJs) { + scripts(options, Program.args[0]).catch((err) => handleError(err, 1)); +} + +// Compress/transpile the javascript files +if (cliOptions.watch) { + watching(Program.args[0]); +} + +// Gzip js/css files +if (cliOptions.compileBs) { + bootstrapJs(); +} + +// Compile codemirror +if (cliOptions.compileCodemirror) { + compileCodemirror(); +} + +// Gzip js/css files +if (cliOptions.gzip) { + compressFiles(); +} + +// Compile the media manager +if (cliOptions.comMedia) { + // false indicates "no watch" + mediaManager(false); +} + +// Watch & Compile the media manager +if (cliOptions.watchComMedia) { + watchMediaManager(true); +} + +// Update the .js/.css versions +if (cliOptions.versioning) { + versioning().catch((err) => handleError(err, 1)); +} + +// Update the url() versions in the .css files +if (cliOptions.cssversioning) { + cssVersioning().catch((err) => handleError(err, 1)); +} + +// Prepare the repo for dev work +if (cliOptions.prepare) { + const bench = new Timer('Build'); + allowedVersion(); + recreateMediaFolder(options) + .then(() => cleanVendors()) + .then(() => localisePackages(options)) + .then(() => patchPackages(options)) + .then(() => minifyVendor()) + .then(() => createErrorPages(options)) + .then(() => stylesheets(options, Program.args[0])) + .then(() => scripts(options, Program.args[0])) + .then(() => mediaManager()) + .then(() => bootstrapJs()) + .then(() => compileCodemirror()) + .then(() => bench.stop('Build')) + .catch((err) => handleError(err, -1)); +} diff --git a/build/media_source/system/js/joomla-core-loader.w-c.es6.js b/build/media_source/system/js/joomla-core-loader.w-c.es6.js index 1e068e856bb83..f19e57056d3db 100644 --- a/build/media_source/system/js/joomla-core-loader.w-c.es6.js +++ b/build/media_source/system/js/joomla-core-loader.w-c.es6.js @@ -46,7 +46,31 @@ class JoomlaCoreLoader extends HTMLElement { const template = document.createElement('template'); template.innerHTML = ` - + diff --git a/build/media_source/system/scss/joomla-core-loader.scss b/build/media_source/system/scss/joomla-core-loader.scss deleted file mode 100644 index a0ad37c5fc150..0000000000000 --- a/build/media_source/system/scss/joomla-core-loader.scss +++ /dev/null @@ -1,26 +0,0 @@ -:host { - z-index: 10000; - display: flex; - align-items: center; - justify-content: center; - overflow: hidden; -} - -:host(.fullscreen) { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - - svg { - width: 345px; - height: 345px; - } -} - -@media (prefers-reduced-motion: reduce) { - .joomla-spinner { - animation: none !important; - } -} diff --git a/build/media_source/vendor/bootstrap/js/index.es6.js b/build/media_source/vendor/bootstrap/js/index.es6.js index 55c058ed881dd..dca3c7f8ce931 100644 --- a/build/media_source/vendor/bootstrap/js/index.es6.js +++ b/build/media_source/vendor/bootstrap/js/index.es6.js @@ -1,14 +1,14 @@ -import Alert from './alert.es6'; -import Button from './button.es6'; -import Collapse from './collapse.es6'; -import Carousel from './carousel.es6'; -import Dropdown from './dropdown.es6'; -import Modal from './modal.es6'; -import Offcanvas from './offcanvas.es6'; -import { Popover } from './popover.es6'; -import Scrollspy from './scrollspy.es6'; -import Tab from './tab.es6'; -import Toast from './toast.es6'; +import Alert from './alert.es6.js'; +import Button from './button.es6.js'; +import Collapse from './collapse.es6.js'; +import Carousel from './carousel.es6.js'; +import Dropdown from './dropdown.es6.js'; +import Modal from './modal.es6.js'; +import Offcanvas from './offcanvas.es6.js'; +import { Popover } from './popover.es6.js'; +import Scrollspy from './scrollspy.es6.js'; +import Tab from './tab.es6.js'; +import Toast from './toast.es6.js'; export { Alert, diff --git a/package-lock.json b/package-lock.json index 22354c1865453..b5e1e426399d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "joomla", - "version": "5.2.0", + "version": "5.3.0", "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { diff --git a/package.json b/package.json index f5bb742c4c863..bec45262426fa 100644 --- a/package.json +++ b/package.json @@ -12,21 +12,21 @@ "npm": ">=10.1.0" }, "scripts": { - "build:js": "node build/build.js --compile-js", - "build:css": "node build/build.js --compile-css", - "build:bs5": "node build/build.js --compile-bs", - "build:com_media": "node --env-file=./build/production.env build/build.js --com-media", - "build:com_media:dev": "node --env-file=./build/development.env build/build.js --com-media", - "watch": "node build/build.js --watch", - "watch:com_media": "node build/build.js --watch-com-media", - "lint:js": "eslint --config build/.eslintrc --ignore-pattern '/media/' --ext .es6.js,.es6,.vue .", + "build:js": "node build/build.mjs --compile-js", + "build:css": "node build/build.mjs --compile-css", + "build:bs5": "node build/build.mjs --compile-bs", + "build:com_media": "node --env-file=./build/production.env build/build.mjs --com-media", + "build:com_media:dev": "node --env-file=./build/development.env build/build.mjs --com-media", + "watch": "node build/build.mjs --watch", + "watch:com_media": "node build/build.mjs --watch-com-media", + "lint:js": "eslint --config build/.eslintrc --ignore-pattern '/media/' --ext .mjs,.es6.js,.es6,.vue .", "lint:testjs": "eslint --config build/.eslintrc --ext .js tests/System", "lint:css": "stylelint --config build/.stylelintrc.json \"administrator/components/com_media/resources/**/*.scss\" \"administrator/templates/**/*.scss\" \"build/media_source/**/*.scss\" \"build/media_source/**/*.css\" \"templates/**/*.scss\" \"installation/template/**/*.scss\"", - "install": "node build/build.js --prepare", - "update": "node build/build.js --copy-assets && node build/build.js --build-pages && node build/build.js --compile-js && node build/build.js --compile-css && node build/build.js --compile-bs && node --env-file=./build/production.env build/build.js --com-media", - "gzip": "node build/build.js --gzip", - "cssversioning": "node build/build.js --cssversioning", - "versioning": "node build/build.js --versioning", + "install": "node build/build.mjs --prepare", + "update": "node build/build.mjs --copy-assets && node build/build.mjs --build-pages && node build/build.mjs --compile-js && node build/build.mjs --compile-css && node build/build.mjs --compile-bs && node --env-file=./build/production.env build/build.mjs --com-media", + "gzip": "node build/build.mjs --gzip", + "cssversioning": "node build/build.mjs --cssversioning", + "versioning": "node build/build.mjs --versioning", "browserlist:update": "npx browserslist@latest --update-db", "cypress:install": "cypress install", "cypress:open": "cypress open --config-file cypress.config.mjs", diff --git a/tests/System/plugins/fs.mjs b/tests/System/plugins/fs.mjs index ae4d35c8da78f..618f28b870e50 100644 --- a/tests/System/plugins/fs.mjs +++ b/tests/System/plugins/fs.mjs @@ -1,7 +1,7 @@ import { chmodSync, existsSync, writeFileSync, mkdirSync, rmSync, -} from 'fs'; -import { dirname, join } from 'path'; +} from 'node:fs'; +import { dirname, join } from 'node:path'; import { umask } from 'node:process'; /**