Problem/Motivation
Internet Explorer is currently the only browser supported by Drupal which doesn't ship with scripting engine that conforms (at least for the most part) with ECMAScript 6. Drupal 10 will drop support for Internet Explorer 11: #3155358: [policy, no patch] Drop IE11 support from Drupal 10.0.x.
The current build tooling requires us to depend on handful of 3rd party dependencies, increasing the cost of maintenance. Requiring a build step, duplicates all JavaScript code, and also makes the contributor experience more complicated, requiring contributors to use additional tooling when working on issues modifying JavaScript.
There could be some reasons to keep the tooling because the way the build tool is set up at the moment, would allow us to utilize features from newer versions of the ECMAScript standard. The tooling reduces the likelihood of accidentally using syntax that isn't supported by all of the supported browsers.
Goals
- Remove a large number of JS dependencies by not needing most of babel toolchain
- Remove code duplication in the source
- Keep naming relevant, in D10 we have a .es6.js file that contains ES6 and a .js file that also contains ES6 code.
- Leave the parts that can be automated to the CI and do not require contributors to compile the resulting JS/CSS code
Proposed resolution
The es6 trick allowed us to use new features for old browsers, now the supported browsers caught up and we don't need this workaround anymore. We can rename all the .es6 files to .js and update all the toolchain we have to remove all the compile/checks steps for JS code.
Use tool like es-check to see if we are using any features not included in ES6 standard, and check browser support for the features not part of ES6 standard manually.
Comments
Comment #2
lauriiiMoving to the Drupal 10 queue.
Comment #3
chi commentedAre there any vital features in the newer ES standards that we need right now?
Comment #4
nod_It's more about enabling than needing at this point.
What it would allow us is to clean up a few things and reduce our dependency on a build step/build tools for core development like outlined in the IS.
Comment #5
droplet commentedA better bundler "strategy" is needed.
Technically, we never needing ES6 also. We've spent time rewriting the scripts instead of only using ES6 in new code. If we remove it now, I think we make a very stupid decision before.
I write everything freely and bundler takes care of the syntax, this is "needing".
I disagreed above. The whole contribution process is below 4 commands:
You need to run all 4 or more if you prepare a 100% good patch before testbot.
I only see the active maintained @babel project is used in CORE (or what I think that's essential), is it really increasing the cost of maintenance? And is the COST increased by 3rd dependencies or Drupal Policy, I think we need to evaluate it. eg. Should we build CKEDITOR5 or other 3rd parties in CORE.
Is it make sense if removing build process also remove "CKEDITOR5 build process in CORE"? It sounds odd to me.
Also, we need to foresee what we do in the future, not only based on the current state. At some point, we will chop code into small files and use import, like below:
https://github.com/twbs/bootstrap/blob/main/js/src/button.js#L8
Are you sure you wanna load 100 or 200 or even more scripts in the browser? What is the cost of import? (the cost is about loading time of multiple files & loading size, no treeshakes) We need to evaluate it now.
Furthermore, what if the 3rd parties we used don't provide an ESM version..etc?
Comment #6
xjmAdding tags for the relevant signoffs for this decision.
I haven't checked with @catch specifically, but anything that means fewer dependencies to manage generally will make the release managers happier. ;)
Comment #7
catchHow does this fit in with #2258313: Add license information to aggregated assets, and the potential follow-up to that issue (which I can't find, but is probably around somewhere) to commit minified versions of core JavaScript?
Comment #8
nod_I'm very much +1 for not doing compiling and limiting ourselves to features available in our supported browser list so we can send the source as-is (and possibly adding the type=module attribute to have older browser stay with the no-js version, contrib could implement the compilation and add a bunch of type=nomodule files for older browsers).
tl;dr: step 1: +1 for modern syntax without babel at the cost of filesize. step 2: smarter aggregator that does the minification (for core files first, then all files after the js label issue is solved).
Currently we do need 4 commands to prepare a good patch (or just 2 if we use
./core/scripts/dev/commit-code-check.sh) and removing the compiling will not remove the lint/spellcheck/prettier steps BUT it would be nice to not have 2 version of the same script in the source, and it is more straightforward for people who are not so familiar with core code.One issue to solve is the aggregation, there are several problems:
I've been thinking about how to do all this without adding a runtime dependency on nodejs for Drupal, and I think we could make a basic PHP version of an es6 bundler (it will not be fancy, no tree shaking, etc.) and basic minification based on https://github.com/mck89/peast (it's looks pretty well maintained, keeping up to date with js syntax and works on php 8.1). Not sure about the overhead, it'll probably need #1014086: Stampedes and cold cache performance issues with css/js aggregation for this to work properly.
At some point we might want to have a CSS parser too to solve things like #2936067: CSS aggregation fails on many variations of @import in a more robust way than putting 3 different regex together, or the still open #646246: Only move non-resolved @import rules to top of aggregate stylesheet when also at top in own stylesheet.
Comment #9
catchOn-the-fly minification definitely needs #1014086: Stampedes and cold cache performance issues with css/js aggregation, this is one of the reasons I worked on it in the first place. But had also given up on it because things were moving away from PHP minification (even ten years ago), but if https://github.com/mck89/peast is promising, that could be great!
Comment #10
nod_updated the IS.
for #5 about bundler stategy I agree we need to think about it, and it is a different topic than babel and the build step for me, so should be in a followup I think.
I'd like to refocus a bit so for the build step we can rename all .es6.js files to .js and we're pretty much done as far as the build step is concerned. I don't think it means we made a stupid decision before, it just mean we implemented the workaround to use ES6 with legacy browsers in a very basic way and built tooling to support that. All of this is not necessary anymore since we can ship es6 code directly.
This issue could simply be named "rename all .es6.js files to .js"
Comment #11
nod_Spent some time to get a bit more info about our packages. The various commands and tool available work on the whole node_modules directory, not just the stuff we declare in the package.json so spent some time writing some code to do just that.
In the file
yarn.tree.txt, for each dependency declared in package.json there is the list of all dependencies (recursively, as declared in the yarn.lock file).In the file
yarn.shared.txt, there is a list of all the packages that are reused, which declared dependency it comes from, which version is installed and which version was required.In the file
yarn.unique.txt, there is a list of all the packages that are required by only one parent dependency.It's a bit clearer the impact removing a dependency will have with this hopefully.
Comment #12
nod_Comment #13
nod_We just had a call with @lauriii, @justafish, and myself to talk about this topic, essentially we could have a solution for D10+ only, which is to rename all .es6.js files to .js and send them as-is. For postCss we would need to ensure that it's needed in D10+ and hopefully remove it since browsers can do a lot nowdays (similar to #8 step 1).
We talked about going ahead with the svelte version of the project browser in #3263443: Consider removing SvelteJS in favor of vanilla JavaScript which would put the topic back on the table, but for now we don't have a good solution.
Comment #14
xjmComment #15
catchGiven #3278415: Remove usages of the JavaScript ES6 build step, the build step itself, and associated dev dependencies can this be closed? Seems like the resolution is to remove the build step, and we have a viable approach for #3302755: On-the-fly JavaScript minification which was my only concern about removing it.
Comment #16
longwaveThe IS suggests using
es-checkto ensure that we only use ES6 compatible code, should we add that as a postponed followup to #3278415: Remove usages of the JavaScript ES6 build step, the build step itself, and associated dev dependencies and then be done with this?Comment #17
nod_+1
Comment #18
catch#3308122: Pre-minify core JavaScript.
Comment #19
wim leersComment #20
wim leers#3278415 is RTBC: #3278415-57: Remove usages of the JavaScript ES6 build step, the build step itself, and associated dev dependencies.
Per #15 … I think we can close this?
I think this only still needs the postponed follow-up that @longwave mentioned in #16?
Comment #21
nod_yeah need the followup and we can close this
Comment #22
catchComment #23
longwaveOpened #3308785: Ensure we only use allowed JavaScript syntax
Comment #24
wim leersThanks! Linked relevant issues to that new issue.
This is done :)