On the latest topic I've been very critic of the approach taken and even tried to propose a different one to avoid some well known problems on PLIP 1896. Unfortunately this was not understood at the time and I just gave up because we didn't had use cases to justify the migration to Plone 5.
This has started to change in latest months and we can't continue kicking the can down the road any longer: Python 2.7 will be EOL in 2020, Zope 4 has been released, and there has been a lot of work lately to make Plone compatible with Python 3.
IMO, Plone 5 resource registries are complex and must be avoided for many reasons as stated in the PLIP aforementioned:
- the revolutionary approach chosen (rewrite everything) has proven buggy and difficult to maintain, as shown by the many issues reported over the last years (the latest opened just 2 days ago)
- some of the JavaScript tools used at the time (Bower, Grunt, RequireJS…) are less attractive nowadays than more modern options like npm, Yarn and webpack
- resource bundling was a workaround for a limitation of the HTTP/1.1 protocol and not a CMS feature; HTTP/2 made this unnecessary and even undesirable
- LESS is now way less popular than SASS
I still think that every add-on author must be able to use the tools of their choice, and I still think Plone should not have to worry about resource bundling.
In early 2016 we selected webpack for our projects and in early 2017 we developed a Buildout recipe (called sc.recipe.staticresources) to make the inclusion of it into the Plone ecosystem easier. Over the past 2 years we have been developing, testing, and enhancing this approach in many add-ons and projects. But the resource registries were still there…
Not anymore.
I'm pleased to announce the release of collective.lazysizes 4.1.1.1, the first add-on that uses a new and very opinionated approach on how to handle static resources in Plone: we just deprecated resource registries in favor of a viewlet registered in plone.htmlhead. This simplifies maintenance among multiple Plone versions and avoids bundling of unrelated resources.
How does it work?
We use webpack to generate all static resources (in our case, a JavaScript file, a page template and an icon; check the webpack.config.js file). The page template is used for the viewlet and includes the following code on it:
<script async="" src="https://www.example.com/++resource++collective.lazysizes/lazysizes-43c36fc.js"></script>
As you can see, the JavaScript id already includes a hash (lazysizes-43c36fc.js), so you don't have to worry about cooking resources, neither caching the wrong file. The hash will only change if the related code changes.
(To understand better the work done, check the following pull requests: Deprecate resource registries and Create JS resource with unique ID.)
What are the benefits of this for developers?
- you can work on your project using latest state-of-the-art JavaScript technologies like ES2015 and Vue.js
- you don't have to worry about resource registries anymore as this approach works out of the box in all Plone versions: no more duplicated registrations, cleaner and simpler ZCML and XML files
- you don't have to worry about upgrade steps anymore (at least the ones related with resource registry cooking/bundling)
- you end up with better static resources: all CSS and JS files minimized, all images optimized
- your code will be faster, as rendering a viewlet is less expensive than rendering a resource in the registry (at least, in Plone 4.3)
- less steps to upgrade your sites
- less unneeded cache invalidations
- faster sites as resources can be loaded in parallel
Now you can concentrate in the things that matter and stop worrying about the ugly parts; isn't that fun?
Share and enjoy!