- 🇫🇷France andypost
As core moved to es6 probably now we need to render
nomodule
as default toscript
tags https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#module_...
We don't have an helpful way of structuring JS in Drupal core. We have Drupal.behaviors
and drupal_add_js
. This makes code reuse hard and it's an issue when a script has dependencies. Usually you have to play with the weight option of drupal_add_js
to make sure the script is loaded at the right place. This is not a good way to manage dependencies. See at the end what this means for maintainers and contrib.
Using AMD would allow us and contrib to rely on an open and well tested specification https://github.com/amdjs/amdjs-api/wiki/AMD. Several implementations exists, we/contrib won't be locked in with a particular library. Having pluggable JS processing will make it possible if not easy to change the library implementing AMD if someone don't like what is used by core.
AMD loaders have scripts to bundle all the dependencies into one single file removing the problem of having a lot of small files to load. This might need some work since most of them work with node.js/rhino and not PHP.
Having an AMD loader means we'll be loading a 5kb-ish (and in some cases, much less) file to bootstrap the loading process of the rest of the files async. This reduces the time it takes to parse and load the page by a very significant %. Loading everything on page load is also an option if there is a need to support that.
Drupal.behaviors
monkey-patching we currently have.Drupal.settings
by targeting settings for specific JS modules (or not).Drupal needs to be more involved in the way JS is managed to make JS fast by default for core and especially for contrib. AMD is the only solution we have right now to have Javascript modules that are not bound to a specific JS library or implementation, only to a spec.
This is what it looks like:
MyModule.js
define(["jquery", "drupal"], function ($, Drupal) {
return {
"run": function () {
/* do something */
}
};
});
SomeOtherFile.js
// using the previous module somewhere else
require(["MyModule"], function (MyModule) {
MyModule.run();
});
You can see that there is no need to file-level closure anymore.
Using an AMD-compatible loader makes on-demand loading easy and could look something like this:
require(['require', 'jquery'], function (require, $) {
$('#ajax-link').click(function (e) {
e.preventDefault();
var href = this.href;
require(['ui.modal'], function (modal) {
modal.open(href);
});
});
});
This particular example loads the modal component and all it's dependencies (it can be CSS, JS, JSON or some TXT file for templating) when the link is clicked, not on page load.
Some slides that can help grasp the issue: http://unscriptable.com/code/Using-AMD-loaders/
This will make contrib life easier.
"drupal"
refers to the file at "core/misc/drupal.js"
. We'll have to introduce a hook in PHP to make that work.use!
plugin linked to earlier.Example of contrib js:
(function ($, Drupal) {
Drupal.behaviors.myCustomBehavior = {
attach: function (context, settings) {
},
detach: function (context, settings, trigger) {
}
};
}(jQuery, Drupal));
What it will look like with AMD:
define(["jquery", "drupal"], function ($, Drupal) {
Drupal.behaviors.myCustomBehavior = {
attach: function (context, settings) {
},
detach: function (context, settings, trigger) {
}
};
});
You're replacing the closure with a function. That's about the only change it will involve on your javascript files.
This change is a proposal to use AMD as it was intended. This is not another NIH issue. We chose a JS loader implementing AMD among the good number of already existing/working/having a test suite AMD loaders, and use that.
Here is the sandbox: https://drupal.org/sandbox/nod_/1545078
The sandbox is working and all JS is turned into AMD. like mfer noticed, there are a couple of non-Drupal JS that has been modified to declare them as AMD modules. Aggregation is not possible yet. Currently using 10 js files will load 10 js files, that's no good.
use!
them properly with the loader.Closed: won't fix
9.0
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
As core moved to es6 probably now we need to render nomodule
as default to script
tags https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#module_...