User tests: Successful: Unsuccessful:
Pull Request for Issue #12402, improved version of #8913 .
The patch introduce new class WebAssetRegistry
to manage the assets, and it's dependencies.
The assets - > read as CSS/JS library.
All registry information stored in a registry file, a simple json
file called joomla.asset.json
.
I made an example for media/vendor/joomla.asset.json
, media/system/joomla.asset.json
, and for each template atum/joomla.asset.json
, cassiopeia/joomla.asset.json
.
The Registry file are for:
atum/joomla.asset.json
where overridden bootstrap.css
, and font-awesome
).To add your registry file:
Factory::getContainer()->get('webasset')
->addRegistryFile('media/blabla/path/joomla.asset.json')
How to use, enable/disable assets:
/** @var Joomla\CMS\WebAsset\WebAssetRegistry $wa */
$wa = Factory::getContainer()->get('webasset');
// Enable Core asset
$wa->enableAsset('core');
// If the asset do not exists, then Exception will be thrown
// Disable Bootstrap CSS
$wa->disableAsset('bootstrap.css');
// bootstrap.css - is an asset name, not a file name !!!
// look in media/vendor/joomla.asset.json to see why
NOTE: Method enableAsset()
/ disableAsset()
do NOT add anything to the document. It just change the asset state. The files of all active assets will be attached to the Document on before header rendering.
By default WebAssetRegistry
use a "lazy loading" of assets.
The registry file parsed only when WebAssetRegistry
requested for new asset.
All dependencies will be resolved while attaching WebAssetRegistry to the document. See WebAssetRegistry::attach()
Also I have made an example in behavior.core
, bootstrap.framework
.
Allow custom class per asset, that can handle stuff like in 'behavior.core':
function onBeforeAtach() {
$doc->addScriptOptions('system.paths', [
'root' => Uri::root(true),
'rootFull' => Uri::root(),
'base' => Uri::base(true),
]);
}
In theory, this allow to clean up JHtml from adding a scripts.
For now feedback are welcome!
yes, if it will be accepted
ping @wilsonge @mbabker @dgrammatiko @C-Lodder @laoneo
also everyone else who doing frondend stuff
Status | New | ⇒ | Pending |
Category | ⇒ | Administration Templates (admin) Repository JavaScript Libraries Front End Templates (site) |
Labels |
Added:
?
?
|
is there some debugging (implemented already) ? or can such debugging be added ?
sure, WebAssetRegistry::getActiveAssets()
, WebAssetRegistry::getAssetsByState()
and small debuging method I made for temporary WebAssetRegistry::debugAssets()
also can do:
$asset = $WebAssetRegistry->getAsset('blabla');
if ($asset && $asset->isActive())
{
echo "it alive!!! (:";
}
what has already been registered for added by some previous call and by who
you cannot check "by who", but can check where the asset comes from.
The asset object has assetSource
property which holds reference to the registry file,
so can use var_dump($asset)
to see from where it come from.
hmm, currently there nothing like WebAssetRegistry::getAllAvailableAssets()
There appears to be inconsistent use of the minified files
There appears to be inconsistent use of the minified files
where the inconsistent?
in build/build-modules-js/settings.json
I assume they should all be minified - they're not
Personally, I'd rather all new events have their own Event subclasses versus everything being dispatched with the generic event class.
public function onWebAssetStateChanged(Event $event): void
{
$asset = $event->getArgument('asset');
}
versus
public function onWebAssetStateChanged(WebAssetStateChangedEvent $event): void
{
$asset = $event->getAsset();
}
You get a better self-documenting API versus having to find the triggering source code to see exactly what arguments are available.
@Fedik nice to see that you're pushing this idea (I was always counting that you will come up with such a PR, thus I never actually deleted the assets lines in the build tools
There are some consideration that the production team should consider here:
Everything in the Javascript world is becoming a module, so I guess there should be a way to manage modules along the old es5 scripts. (small explanation here: if you have a <script type="module" src="blabla.js">
by default this script is deferred and scoped differently than a normal es6 script. This obviously imposes some challenges with jQuery scripts and the order of execution but it's another talk altogether).
I would expect J4 to be able to handle critical/lazy-loaded assets, at the end of the day these are the current best practices...
If you keep JHtml::script
, JHtml::stylesheet
, addScript
, addStylesheet
(also some bright minds are using the addCustomTag
to inject css or js), then there will be way too many options to handle assets which obviously will make the dev life more complicated instead of simplifying things. So the question (this goes to the production team) is: are you willing to break the current status quo?
The problem is not with require.js or any of that tooling. The problem is you are in an environment where there is an end user facing feature for runtime resolution of assets that enables end users to create overrides. You aren't working in a purely compiled environment, you aren't working in an environment where all the paths are going to be static.
If the JavaScript and browser tooling reach a point where the capabilities that Joomla has can be emulated in a way other than what JHtml does to resolve paths at runtime, that can be considered. Until then, talking down on the project because it doesn't push for a compiled build environment that only "real" developers can use does nothing but make people feel alienated.
you aren't working in an environment where all the paths are going to be static
require.js can handle this in the same manner script tags are appended in the html.
talking down on the project because it doesn't push for a compiled build environment
You got me wrong, all I said was that you should try to ease the path for modules (by forcing defer) not actually implement it right now (yes till dynamic imports are supported everywhere there's no point even trying to do it)
The problem is you are in an environment where there is an end user facing feature for runtime resolution of assets that enables end users to create overrides.
After some tweaks WebAssetRegistry allow to generate a config for require.js, which can be used as script/module loader.
but all this not in current PR
@mbabker Here another example about what is doing enable/disable and add/remove methods:
// Empty asset registry
$wa = new WebAssetRegistry;
// Add some assets
$wa->addAsset(new WebAssetItem("🍻"));
$wa->addAsset(new WebAssetItem("🐘"));
// At this point we have 2 asset in registry, with STATE_INACTIVE
// So nothing will be added to Document
$wa->attachActiveAssetsToDocument($document); // Will do nothing, because all assets is inactive
// Enable asset
$wa->enableAsset("🐘");
// At this ponit we still have 2 assets, but only 1 is Active
$wa->attachActiveAssetsToDocument($document); // Will add files from "🐘" asset to Document
// Try to enable not-existing asset
$wa->enableAsset("🐛"); // Will throw Exception
And use of RegistryFile just doing addAsset()
for you, all you need is just enable/disable existing.
Of course you still can do $wa->addAsset(new WebAssetItem("🍪"))->enableAsset("🍪")
, if need.
Status | Pending | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2018-10-14 21:49:35 |
Closed_By | ⇒ | wilsonge |
Let's take this as a first pass. I'm pretty sure there's some improvements to be made here - but I'm happy with this as the base concept
oh, that was fast
for note, one issue left:
@mbabker : If I enable an asset with dependencies I expect the dependencies to be enabled as well.
This might be a case of trying to be too lazy. It's fine to defer parsing the JSON files until you actually start adding WebAssetItem entries to the internal store, but once you start populating WebAssetRegistry::$assets with objects it should always contain the full resource tree. It really shouldn't be a partial snapshot.
I think it is pretty important.
I will try to fix it, in one of next pull request.
I've started working on docs for this feature https://docs.joomla.org/J4.x:Web_Assets Any help is always appreciated!
Looks very nice,
is there some debugging (implemented already) ? or can such debugging be added ?
WebAssetRegistry::attach()
) ?$wa->enableAsset('template.atum.' . ($this->direction === 'rtl' ? 'rtl' : 'ltr'));
i mean without looking and figuring out ourselves dependencies out of the json files
but also to help verify what we put inside the json file is correct