Skip to content
Open
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
1f1d8e9
Building build
Fedik Jan 31, 2026
35e4913
Building build
Fedik Jan 31, 2026
7d20a5b
Building build logs
Fedik Jan 31, 2026
45d4647
Building build logs
Fedik Feb 1, 2026
936e81a
Building build logs
Fedik Feb 1, 2026
fbc2c09
Building build
Fedik Feb 1, 2026
4b5c32d
Building build
Fedik Feb 1, 2026
78d72d7
Building build css
Fedik Feb 1, 2026
d15d54c
Building build css
Fedik Feb 1, 2026
bab2b4f
Building build css
Fedik Feb 1, 2026
f33080f
Building build css
Fedik Feb 1, 2026
94a2ffd
Building build css
Fedik Feb 1, 2026
b65573f
Building build css
Fedik Feb 1, 2026
56324c2
Building build css
Fedik Feb 1, 2026
60a1481
Merge branch '6.1-dev' into building-build-js
Fedik Feb 7, 2026
baa1c3c
Building build js
Fedik Feb 7, 2026
009096d
Building build js
Fedik Feb 7, 2026
653fcc2
Building build js
Fedik Feb 7, 2026
357e2ec
Building build js
Fedik Feb 7, 2026
ec5ed2d
Building build js
Fedik Feb 7, 2026
fabdc9c
Building build builders
Fedik Feb 7, 2026
fb46051
Building build
Fedik Feb 7, 2026
c58b478
Building build vendor
Fedik Feb 7, 2026
e4bbfbb
Building build vendor
Fedik Feb 7, 2026
0439e91
Building build vendor
Fedik Feb 7, 2026
56a89f6
Building build vendor
Fedik Feb 7, 2026
b40305d
Merge branch '6.1-dev' into building-build-js
Fedik Feb 8, 2026
cef4260
Building build vendor
Fedik Feb 8, 2026
b44a93e
Building build vendor
Fedik Feb 8, 2026
a8b4936
Building build vendor
Fedik Feb 8, 2026
d3a6b80
Building build vendor
Fedik Feb 8, 2026
39baf22
Building build vendor
Fedik Feb 8, 2026
ffff1a1
Building build vendor
Fedik Feb 8, 2026
843bf7c
Building build
Fedik Feb 8, 2026
23abfa2
Building build vendor
Fedik Feb 8, 2026
fa29cf6
Building build vendor
Fedik Feb 8, 2026
c66fa0c
Building build vendor
Fedik Feb 8, 2026
fe3e58f
Building build blocking
Fedik Feb 8, 2026
61e1c6a
Building build vendor clean
Fedik Feb 8, 2026
02ea95f
Building build tinymce
Fedik Feb 8, 2026
c293ef2
Building build Codemirror
Fedik Feb 8, 2026
2422128
Building build Codemirror
Fedik Feb 9, 2026
ccd83a6
Building build plg debug
Fedik Feb 9, 2026
8981c18
Building build plg debug
Fedik Feb 10, 2026
e2b6573
Building build no copy deps
Fedik Feb 10, 2026
742fb3f
Building build media
Fedik Feb 10, 2026
b703b36
Building build codemirror without progress bar
Fedik Feb 10, 2026
ebe126e
Building build bootstrap
Fedik Feb 10, 2026
69b0245
Building build
Fedik Feb 10, 2026
b9753dd
Building build error pages
Fedik Feb 10, 2026
fc4deeb
Building build error pages
Fedik Feb 10, 2026
4b138c2
Building build
Fedik Feb 10, 2026
7688774
Building build
Fedik Feb 10, 2026
77a810e
Building build
Fedik Feb 10, 2026
5f516e9
Building build
Fedik Feb 10, 2026
6b4ebda
Building build bootstrap
Fedik Feb 11, 2026
0aa6eec
Building build remove unused
Fedik Feb 11, 2026
01a16a8
Building build remove unused
Fedik Feb 11, 2026
019babb
Building build compress
Fedik Feb 11, 2026
cdffcae
Building build remove unused
Fedik Feb 11, 2026
d545b8a
Building build watch
Fedik Feb 11, 2026
6ea23db
Building build watch
Fedik Feb 11, 2026
3799e6d
Building build watch
Fedik Feb 11, 2026
95fa31c
Building build watch
Fedik Feb 11, 2026
66ca9a0
Building build watch
Fedik Feb 11, 2026
dd694ab
Building build remove unused
Fedik Feb 11, 2026
46a330f
Building build watch
Fedik Feb 11, 2026
a21f528
Building build watch
Fedik Feb 11, 2026
a169deb
Building build move com_media
Fedik Feb 11, 2026
426d962
Building build move com_media
Fedik Feb 11, 2026
59d1cd9
Building build move com_media
Fedik Feb 11, 2026
b99719b
Building build
Fedik Feb 11, 2026
394d44f
Merge branch '6.1-dev' into building-build-js
Fedik Feb 12, 2026
8e7c95e
Building build
Fedik Feb 12, 2026
cdb7b4a
Building build move workflow
Fedik Feb 12, 2026
b61fd6a
Building build
Fedik Feb 12, 2026
d9e1760
Building build
Fedik Feb 12, 2026
9a092ac
Building build move source
Fedik Feb 12, 2026
7bbc777
Building build move source
Fedik Feb 12, 2026
95f5703
Building build
Fedik Feb 12, 2026
d8a3c5b
Building build
Fedik Feb 12, 2026
36d2fb6
Building build read
Fedik Feb 12, 2026
cd6dcaa
Building build read
Fedik Feb 12, 2026
de825ab
Building build read
Fedik Feb 12, 2026
9c6a178
Building build read
Fedik Feb 12, 2026
f4f4735
test
Fedik Feb 12, 2026
639edac
test
Fedik Feb 12, 2026
641fc5b
test
Fedik Feb 12, 2026
973a734
Dirent parentPath not path
Fedik Feb 12, 2026
c6ef470
Building build read
Fedik Feb 12, 2026
fe90c0f
css cs
Fedik Feb 12, 2026
57f7b97
Merge branch '6.1-dev' into building-build-js
Fedik Feb 12, 2026
9239795
fixes
Fedik Feb 12, 2026
2bfc542
upd
Fedik Feb 12, 2026
0ab21e2
note
Fedik Feb 12, 2026
7bb2feb
Building build remove unused
Fedik Feb 12, 2026
99bd97c
Apply suggestions from code review
Fedik Feb 13, 2026
60755bd
Update build/build-modules-js/command/build-command.mjs
Fedik Feb 13, 2026
24cc682
Merge branch '6.1-dev' into building-build-js
Fedik Feb 13, 2026
e0ecb49
Merge branch '6.1-dev' into building-build-js
Fedik Feb 14, 2026
b338040
test
Fedik Feb 14, 2026
84ecccb
test
Fedik Feb 14, 2026
897b3d9
test
Fedik Feb 14, 2026
253b8c6
test
Fedik Feb 14, 2026
e30c78d
test
Fedik Feb 14, 2026
f08077c
test
Fedik Feb 14, 2026
027c27b
test
Fedik Feb 14, 2026
ecf224a
test
Fedik Feb 14, 2026
b9feb2b
test
Fedik Feb 14, 2026
90cba90
test
Fedik Feb 14, 2026
8a77a06
test
Fedik Feb 14, 2026
b3cf483
test
Fedik Feb 14, 2026
bc564ba
test
Fedik Feb 14, 2026
6859e3f
test
Fedik Feb 14, 2026
2ff79bf
test
Fedik Feb 14, 2026
3bf1aaa
Building build
Fedik Feb 14, 2026
f7f3431
test
Fedik Feb 14, 2026
857ae77
test
Fedik Feb 14, 2026
5ebca26
Merge branch '6.1-dev' into building-build-js
Fedik Feb 21, 2026
8544521
upd
Fedik Feb 21, 2026
fbdc90e
Merge branch '6.1-dev' into building-build-js
Fedik Mar 1, 2026
269414d
Merge branch '6.1-dev' into building-build-js
Fedik Mar 3, 2026
02675c9
fix
Fedik Mar 3, 2026
4e521b9
Merge branch '6.1-dev' into building-build-js
Fedik Mar 3, 2026
304cbc8
Merge branch '6.1-dev' into building-build-js
Fedik Mar 5, 2026
9c6ab74
fix bs
Fedik Mar 5, 2026
342fe7d
keep license comments
Fedik Mar 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
57 changes: 12 additions & 45 deletions build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,32 @@ Joomla provides a set of tools for managing static assets and dependencies based
The responsibilities of these tools are:
- To copy files from the `node-modules` folder to the `media` folder.
- Do any transformations on the copied files.
- Update the version numbers on the XML files of the TinyMCE and CodeMirror editors.
- Copy files from the `build/media_source` folder to the `media` folder.
- Copy files from the `media_source/` folder to the `media` folder.
- Transform any modern JS to ES2017 and transpile it to ES5.
- Transform any SCSS file to the respective CSS file.

For some of these operations, conventions were established to simplify and speed up the process.

## Javascript
There are three options here:
- Modern Javascript files must have an extension `.es6.js`.
This allows ESLint to check the code style, Joomla is using the Airbnb preset https://github.com/airbnb/javascript.
It also instructs Rollup to do the transforms for ES2017. This step creates both normal and minified files.
Production code WILL NOT have the `.es6` part for ES2017+ files.
Read more at [CMS Media source](../media_source/README.md).

- Web Component Javascript files must have an extension `.w-c.es6.js`.
This allows ESLint to check the code style and instructs Rollup to do the transforms for ES2017. This step creates normal and minified files. The difference with the `.es6` files is that the tools will automate the minification of the CSS (assuming that the appropriate SCSS file exists), which is then injected into the JS file in place of the placeholder `{{CSS_CONTENTS_PLACEHOLDER}}` (ie: `build/media_source/system/js/joomla-core-loader.w-c.es6.js`)
Production code WILL NOT have the `.w-c.es6` part for ES2017+.

- Legacy Javascript files must have an extension `.es5.js`.
This instructs ESLint to skip checking this file.
Also, it instructs the tools to create a minified version (production code WILL NOT have the `.es5` part)

- Javascript files with only an extension `.js`.
These files will be ignored by the build tools.

## SCSS
- SCSS files starting with `_` will not become entry points for SCSS.
SCSS files will be transformed to CSS, both normal and minified versions.

## CSS
- CSS files will only get minified.
## NPM Commands

- `npm run builders-list` Show list of available builders in order of execution.
- `npm run build` Build assets with production env. Extra arguments is required check [CMS Media source](../media_source/README.md#building-assets).
- `npm run build:dev` Build assets with development env. Extra arguments is required check [CMS Media source](../media_source/README.md#building-assets).
- `npm run watch` Start files watcher for specified asset with production env. Example `npm run watch -- -n com_content` for `com_content` assets.
- `npm run watch:dev` Start files watcher for specified asset with development env.
- `npm run lint:js` Checks the code style for the JavaScript/Vue files
- `npm run lint:testjs` Checks the code style for the JavaScript/Vue files under `tests/System` used for testing.
- `npm run lint:css` Checks the code style for all SCSS files.
- `npm run gzip` Creates `.gz` files for all the `.min.js` and `.min.css`.

## NPM Commands
- `npm run build:js`: compiles ALL the JS (excluding Bootstrap and Media Manager).
- `npm run build:js -- build/media_source/com_actionlogs`: compiles ALL the JS ONLY in the folder `build/media_source/com_actionlogs`.
- `npm run build:css`: compiles ALL the SCSS.
- `npm run build:css -- templates/cassiopeia`: compiles ALL the SCSS ONLY in the folder `templates/cassiopeia`.
- `npm run build:bs5`: Builds the Bootstrap Javascript components.
- `npm run build:com_media`: Builds the Media Manager Vue Application.
- `npm run build:com_media:dev`: Builds the Media Manager Vue Application but in DEV mode, (no minification, no es5 and all flags for the vue devtools)
- `npm run lint:js`: Checks the code style for all the Javascript/Vue files.
- `npm run lint:js -- --fix`: Checks and fixes the code style for all the Javascript/Vue files (might not fix everything).
- `npm run lint:css`: Checks the code style for all SCSS files.
- `npm run lint:css -- --fix`: Checks and fixes the code style for all SCSS files (might not fix everything).
- `npm run gzip`: Creates `.gz` files for all the `.min.js` and `.min.css`.
- `npm run versioning`: Creates the correct version hash for all the assets inside the joomla.asset.json files (excluding templates).

## Working Efficiently with the Joomla Build Tools

Usually, the scope of a single contribution to the project should be limited. For example: fixing a CSS bug, a Javascript bug, some Markup, or a bug that involves changes in all these areas. The build tools were created so that you spend less time on compiling assets than testing a possible solution.

*Embrace the watchers*
Let the computer help you succeed faster and safer. There are 2 watchers at the moment: one for the Media Manager (client app based on VueJS) and another one that handles templates and the source (build) folder.

Assuming that you are working on the Media Manager, you can run in your terminal (already in the root folder of the Joomla repo) `npm run watch:com_media`. This watcher will automatically recompile the app on every save (there is a debounce of 0.3s, so if you have autosave it will be a clever way to minimise the wait).

Assuming that you are working on the Web Authentication JavaScript, you can run in your terminal (already in the root folder of the Joomla repo) `npm run watch -- build/media_source/plg_system_webauthn`. This watcher will automatically recompile any JavaScript file inside the folder `build/media_source/plg_system_webauthn/js` on every save. But there's more! Since you asked the watcher to check the parent folder (eg `build/media_source/plg_system_webauthn`), you can also edit the SCSS files in the `build/media_source/plg_system_webauthn/scss` or the CSS files in `build/media_source/plg_system_webauthn/css`. The same example for editing some SCSS in the Cassiopeia template would require a command like: `npm run watch -- templates/cassiopeia/scss`.

Once you get your code doing what it is meant to do, make sure that you check you are not breaking any of the Code Style rules by running `npm run lint:css -- --fix` and `npm run lint:js -- --fix` (the `-- --fix` will try to fix anything that's not trivial).

Happy coding
79 changes: 79 additions & 0 deletions build/build-modules-js/builder/builder-factory.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Builder factory class
*/
import path from 'node:path';
import fs from 'node:fs';
import DefaultModuleBuilder from './default-module-builder.mjs';

export class BuilderFactory{
constructor(basePath = '', targetPath = '', cmdOptions = {}) {
this.basePath = basePath;
this.targetPath = targetPath;
this.cmdOptions = cmdOptions;
}

async createBuilder(name) {
// Module path
let modulePath = path.join(this.basePath, name, 'builder.mjs');

// Check if we have the builder module
if (!fs.existsSync(modulePath)) {
// Use default module
return new DefaultModuleBuilder(name, this.basePath, this.targetPath, this.cmdOptions);
}

return import(modulePath).then((module) => {
return new module.default(name, this.basePath, this.targetPath, this.cmdOptions);
});
}
}

/**
* Create and run the builder
*
* @param { Command } program
* @param { String } name
* @param { BuilderFactory } factory
* @param { string[] } tasksToRun
* @param { boolean } skipUndefinedTask
* @return { Promise }
*/
export const createAndRunBuilder = async (program, name, factory, tasksToRun = [], skipUndefinedTask = false) => {
return factory.createBuilder(name)
.then((builder) => {
if (!builder.getBuildTasks) {
program.error(`Builder module for "${name}" should provide "getBuildTasks()" method. Which used to determine which task can be run for the builder.`)
}
console.log(`Initialize build [${name}]`);

// Run tasks for given builder
const allTasks = builder.getAllTasks ? builder.getAllTasks() : builder.getBuildTasks();
let lastPromise = Promise.resolve();
(tasksToRun.length ? tasksToRun : builder.getBuildTasks()).forEach((taskName) => {
// Check whether the task is allowed for active builder
if (!allTasks.includes(taskName)) {
// Show error when the builder and the task was specified, and it is not applicable for active builder.
if (!skipUndefinedTask) {
program.error(`Task "${taskName}" is not applicable for "${name}" builder.`);
}
return;
}

// Execute the task sequentially, this is needed because task may depend on each other
lastPromise = lastPromise.then(() => {
console.log(`Start task [${name}::${taskName}]`);

return builder[taskName]().then(async () => {
console.log('\x1b[32m%s\x1b[0m', `Completed task [${name}::${taskName}]`);
}).catch((error) => {
console.log('\x1b[31m%s\x1b[0m', `Failed Task [${name}::${taskName}]`);
console.trace(error);
program.error(error.message);
});
});
});
return lastPromise;
}).then(() => {
console.log('\x1b[32m%s\x1b[0m', `Completed build [${name}]`);
});
};
Loading
Loading