Drupal 8's Asset Management Rant

It has been about half a year since I wrote my Angulars Drupal 8 module and posted it on GitHub. The module actually did some easy manipulation with strings and inputs by AngularJS. Now that I have had some free time in a few months, I decided to revisit it and see if it still worked with all the changes being bundled into Drupal 8 daily. And surely it did not. One thing that changed in Drupal 8 recently (well, a few months ago) has made me especially ranty. Namely, that the possibility to add assets such as js and css directly to render arrays has been removed.

Drupal 7 was very very flexible at adding js and css assets. You could add them in templates, you could add them in preprocess, in render arrays through the #attached key, and in theme and module info files. Especially adding css and js to node render arrays and forms with the #attached key has been my delight, since assets could be easily added to specific pages and form elements, without having to influence the site config or theme or module config. Then, with Drupal 8, there began an assault on that flexibility, first with drupal_add_js() removed. It has only been a few months before, that web sites were describing the #attached as if not the best option to add assets in Drupal 8, like here and there, and good bye to Drupal's #attached awesomeness!

The logic behind removing drupal_add_js() and js with #attached key has been as follows. There has been a great amount of libraries and assets added to Drupal core, and yet, even more can be added by modules and themes. So, the issue of managing the asses has arisen. And to manage the assets, they needed to be declared in a corresponding module or theme, and were all called libraries. So now these js and css libraries could be #attached. Here is how I made them work in my Angulars module:

File: angulars.libraries.yml

  version: VERSION
    'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.7/angular.min.js':  {type: external}
    js/sample1.js: {}
    js/sample2.js: {}
    js/sample3.js: {}
    js/sample4.js: {}
    js/sample5.js: {}
    - core/jquery
    - core/drupal

And in file: AngularsController.php

public function content() {
$output['#attached']['library'][] = 'angulars/angulars';
$output[] = $this->sample_1();
$output[] = $this->sample_2();
$output[] = $this->sample_3();
$output[] = $this->sample_4();
$output[] = $this->sample_5();


So, it is still #attached, but as a library rather than a script file directly.

Fun? Yeah, but only for some part of it. But it's also grief. While this is a great innovation for the proper libraries, like JQuery and AngularJS to be attached, it is also a PITA for attaching small js scripts, like the sample scripts that I used in my Angulars module, that are not intended to be libraries or called anywhere rather than a specific page.

I also don't buy the argument that this was needed to assets could be managed. Declaring the libraries is required for making them manageable, true enough. But nothing really badly required forbidding of adding custom js and css files to pages and forms for developers who chose to to so. It's like saying that because wearing ties is styly and nice, you have to wear costumes and ties all the time, even if you shower or go to the beach. There are reasons for each use, and it is usually only in the corporate segment that the dress code is actually enforced. Could it be the logic behind this change as well? All the talk about Drupal 8 'going corporate'? True or not, I do think this limitation is artificial and unnecessary.