Plone 5 modernized the CSS and JS development experience by incorporating tools like Bower, Grunt, RequireJS and LESS into it.
In Plone 5, CSS and JS resources for core Plone and add-on packages are managed in a new and completely rewritten Resource Registry that has proven buggy, difficult to maintain, and hard to understand for integrators and non-core developers.
We need to change that story by simplifying it.
While the motivation of the rewritten was very well justified, the final implementation has shown some problems that we need to address ASAP:
Some of these issues have discouraged integrators and add-on developers on using Plone 5.
Plone Framework Team has to discuss around the current toolset, and make a recommendation on its extended usage or its deprecation in favor of more modern options.
That could be difficult, given the current state of JS develoopment.
The proposal is to completely remove the bundling feature from the Plone core backend (probably including all the recently created ++production++ and ++unique++ namespaces) and UI (configlet).
The final result should be something like this:
The following example shows how this could work in practice:
From the add-on developer point of view this is how this should work:
++resource++ namespaceThis reflects more or less the current situation on Plone 4 on that aspect.
Just another change on the way we do things could discourage core and add-on developers, unless we convince them this time will be different and life is going to be easier for them.
The Plone legacy bundle must be removed and a upgrade step must be created to deal with resources already there.
Third party resources bundled in the plone and plone logged-in bundles must be decoupled from there.
What to do with the other existing bundles in Plone 5 (resourceregistry, thememapper…)? Do they still make sense? Probably just in the context of Plone core. Do we need to be able to manage more bundles in the resource registry UI? I don't know.
Currently there is no way to manage conditions per resource, do we want that back?
What about the overrides?
This PLIP is complex and has many obscure aspects that will be evident only after the work is started.
I think this is the biggest challenge we have with Plone 5 right now.
We don't need a tool that works TTW, we need a tool that just work and be as simple as possible.
Count me in!
To be simple we could use a configuration over convention trick, all addons will provide a ++resource++
These files will be generated by grunt, gulp, webpack, name your cool js bundle tool or even a simple file
The more the JS tooling is evolving, the more I think that JS & CSS for Plone should be managed completely separated from Plone itself, i.e. just like we fetch a new package from pypi to get X functionality, we should just do the same with JS, go to npm and install it, bundle it as you see fit and ship it to your users via diazo (i.e. with the theme).
So in a way, as we can upload zipped theme files, if your JS tooling already generates everything, I guess is not that difficult that they generate a zip file as well, ready to upload :-)
Of course, this approach means that any TTW customization is gone, specially regarding CSS. Some good documentation, tutorials and so on could mitigate that shortcoming, although nowadays the average design firm should most probably be well versed with JS tooling to generate some CSS and JS files.
I'll not miss the TTW customization of JS and CSS as far as we still give a simple way to do a ploneCustom.css TTW.
I also share the idea that webpack (and CSS and JS outside Plone) is probably the way to go (at least for 6 months, before JS world will find something new 😃). Let be honest: we have a new resource registry but some top Plone dev today are not using it.
But there's still something that really scare me about this approach: what about add-on development? I've the feeling that releasing Plone add-on with JavaScript and CSS (and JavaScript is every day more important) will be impossible to be done.
And let me say that Plone without add-on is dead.
Nicely thought out and well written. Can't argue with the motivation, though I lack the detailed understanding of the innards.
@keul the add-on python part would be released to pypi and the JS/CSS part on npm, then you will have to update buildout.cfg with the add-on as well as the packages.json :-)
At the end, specially regarding JS/CSS you most probably want to customize them anyway.
@hvelarde
Plone core and add-on developers should enforce a standardized JS dependency management (currently, by using RequireJS)
That's one of the most problematic points. We definitely MUST not enforce anyone doing any JS "the right way" (although I agree that Plone core JS must follow some conventions) All the AMD stuff will vanish into the air as soon as EcmaScript will provide proper dependency management OOTB. By trying to force Plone devs doing JS the one or the other way we'll end up in the same discussion in a year or two again.
The Plone JS story in the past consolidated to the availability of jQuery in Plone 4 and I think this should become the default again without the need of AMD integration simply to make Add-on migration easy while keeping B/C to Plone 4.
The biggest problem with the old RR was dependency management. Let's face it not from the technical JS POV. Dependency management was implemented by inserting resources before or after another resource by name. While this is not really reliable the initial problem would have been solved by giving resources an id and building a dependency tree.
The new RR on the other side solved the problem of technology agnostic dependency management while making assumptions about HOW you need to code JS and which tools you need to use then - which is the main cause of the big JS depression.
So retrospective it might have been better to stick to the old RR, implement proper dependency declarations and provide a way to export this dependency tree as JSON - which then can be used by bower, grunt and so on for bundling... Ok, this possibility is just gone ;) - But we can think about this approach given the new RR declarations from the registry.
@gforcada
Using npm as JS delivery system like we do with pypi for python has some going for it, anyway it also just adds a needless level of complexity to the whole story.
And - way more important - we need to recover a maintainable way for migrating Add-ons from 4 to 5. This implies the need of NOT touching any JS at all in the best case.
I've rewritten the PLIP giving more detailed information of what I think must be done.
@gforcada I'm not propossing to deploy add-ons code at two places now; that's ubercomplicated and not sane, IMO. we must continue using the current approach of installing add-ons because it works; let's change one thing at a time and wait to see how things evolve.
@keul third party add-ons will include their CSS and JS code as they do right now; the only change is we need to handle dependencies in a sane way (currently by using RequireJS) and there's no obligation for resource bundling.
@rnixx I think the problem with the new resource registry was the bundling and not the usage of RequireJS, which is not, per se, big deal.
anyway, as I said before I'm not an expert on the topic, but I think AMDification of all JS code on third party add-ons must be a precondition before moving an add-on to Plone 5; AMD-compatible JS just work OOTB in Plone 4 and is not difficult to implement.
here is an explanation of all those technologies: http://stackoverflow.com/a/16522990/644075
removal of RequireJS at this point is out of the discussion, IMO, at least for the Plone core.
when Plone 6 arrives, and ECMAScript 6 is a reality, we will not have to discuss over all of this again, but just clean up and remove all the crap.
@hvelarde
I think AMDification of all JS code on third party add-ons must be a precondition before moving an add-on to Plone 5; AMD-compatible JS just work OOTB in Plone 4 and is not difficult to implement.
Right now it is a precondition, or at least it's a hack if you want to avoid it. Have you thought about JS used in Plone context but amongst others, skipping AMD deliberately? Why do you want to force ppl having to maintain another version of their JS? I have made a proposal how this can be handled here https://github.com/plone/Products.CMFPlone/issues/1529#issuecomment-210304757 and here https://github.com/plone/Products.CMFPlone/pull/1707#issuecomment-249152928
when Plone 6 arrives, and ECMAScript 6 is a reality, we will not have to discuss over all of this again, but just clean up and remove all the crap.
So we integrate AMD all over the place now to remove it again in the next major release of Plone? Really? Why not make things work next to each other? Count the repos in collective and do an estimation how much work it is to migrate the repos 2 times vs. make the framework deal with the options.
problem with the new resource registry was the bundling
Why? I think the information is good, the way bundle information is resolved and bundles are delivered is bad.
@rnixx here are a couple of documents explaining why AMD is better than the module pattern:
adding a couple of lines to the JS code now (and remove them 2 years later) seems to me no big deal regardless the number of add-ons we maintain, and compared to the time I have to spend in all other things in order to make a package compatible with Plone 5.
having said that, I'm not against what you are saying, I just want to keep the scope of this PLIP limited to get rid of the resource registry bundling as it's currently broken, overrated and completely unnecessary in the short term.
you can create a new PLIP so we can discuss around JS modules if you like.
@hvelarde
here are a couple of documents explaining why AMD is better
It's exactly this attitude why we ended up with the current mess.
Even if AMD is better, non AMD might be the reality of others for a good reason and this reality not changes by ignorance.
You may want to read again my linked comments about how AMD and non AMD stuff can coexist, this PLIP is exactly the right place for dealing with this issue.
Any chance that developers that nowaday are not using RR can jump in there? @hvelarde or @datakurre IIRC?
Sorry but I share the fear of @rnixx about taking the wrong choice.. I suffer the "World if going to jQuery, we choose KSS" syndrome 😃)
@keul Once I moved to webpack I kind of gave up on "activate add-on and go"-approach. And now that I battle with webpack anyway, I'm ok with any JS that webpack can chew.
AMD is not just going to vanish--it's a fine method for defining modules.
"Resource bundling was a workaround for a limitation of the HTTP/1.1 protocol and not a CMS feature; HTTP/2 makes it unnecessary and even undesirable"
I'm not convinced of this. Modern websites bundle 100s, maybe 1000s of files together to build everything. Think of just a theme, various less/scss files, various icons--bundling puts that all together. Now think of an angular app...
Do we really think that there isn't going to be a performance impact on requesting all those resources from Plone opposed to just a couple? Maybe if all those resources are served at a proxy/CDN everything will still be alright. I hope you're right but am waiting to see how it pans out...
But I'm going to try and stay out of it from here. I'm glad there are some taking ownership of this.
@vangheem not ok with a non TTW way to include js in your theme but the the current RR TTW compilation only seems to work sometimes. Some of the time if I want a js in my theme I just include and bypass the registries.
@hvelarde
AMDification of all JS code on third party add-ons must be a precondition before moving an add-on to Plone 5;
As an add-on author, I agree with this, with two possible exceptions: