Problem/Motivation
Core JavasScript contribution flow had been introduced in #2809281: Use ES6 for core JavaScript development and described in Drupal core now using ES6 for javascript development. It's not clear, however, how to use es6 for contrib and custom development. The scripts from core can be used in Drupal projects with a package.json file like this one placed one or two levels above the core folder but it would be nice to be able to use the core API directly in order to to reduce redundancy.
Proposed resolution
Add an option to build and watch scripts. For instance:
yarn watch:js-dev --contrib
or
yarn watch-contrib:js-dev
The option would work exactly the same way as it does for the core js, it would just search for .es6.js files in the parent directory (web/ instead of core/).
API changes
Contrib will be able to use ES6+ if they like.
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | 2957390-23.combined.patch | 533.47 KB | blazey |
| #23 | 2957390-23.for-review.patch | 77.95 KB | blazey |
Comments
Comment #2
blazey commentedComment #3
blazey commentedComment #4
blazey commentedComment #5
dawehner+1 for the idea! Enabling contrib people to use es6 is really nice! One thing to keep in mind though is that they cannot add external packages easily yet, but I think that's fine.
I'm curious whether instead of adding --contrib/--dev or anything like that the simpler option would be a
--diroption.Comment #6
blazey commentedThanks for sharing your opinion @dawehner. Adding the ability to import packages doesn't seem to be easy right now, however, having something like a central webpack entry point would be a huge step forward in terms of JS DX and progressive decoupling.
About the second part,
--diris definitely more versatile. Attaching a patch that adds such an option to build and watch scripts. It defaults to./, so the core workflow remains unchanged.Example usage for contrib / custom code:
babel-core prior to 7.0.0-alpha.3 has a bug in plugin resolution which makes it impossible to process any files that aren't inside the directory with package.json (see Transpile outside of node_module 'root'), so babel-core update was required.
The upgrade caused minor differences in quite a few .js files, so the real changes (excluding those from artifacts) are in a separate file.
Comment #7
blazey commentedComment #9
blazey commentedLooks like babel 7.0.0-beta.3 causes issues in tabledrag. This is the most recent version available on npm, so we might need to wait for a full release.
Comment #10
dawehnerI was curious whether it is possible to see this problem in the diff.
This is one of the differences which could make a difference.
Maybe this makes a negative difference too.
Comment #11
blazey commentedThe exception is thrown in the last line of this snippet
thisdoesn't seem right :)The npm version is 5 months old and there were 39 betas since then (https://github.com/babel/babel/releases), so the issue might have already been fixed. Even if so, we should probably wait until it's on npm.
Comment #12
dawehnerDo you want to try out this locally? Otherwise it might be worth reporting the problem.
Comment #13
chi commentedI am getting the following error with this patch.
The good news is that
yarn run watch:js --dir ../modulesworks well. So the problem lays somewhere in core JS files.Comment #14
chi commentedWell, it does not. The only change in processed file is "DO NOT EDIT THIS FILE." header. I wounder if Babel presets are picked correctly when the root directory is changed.
Comment #16
andyposthttps://github.com/babel/babel/releases/tag/v7.0.0-rc.0 is out
Comment #17
blazey commentedCool. Hopefully, it will hit npm soon: https://www.npmjs.com/package/babel-core.
Comment #18
chr.fritschbabel 7.0 was released a month ago. Can we here proceed now?
Comment #20
dawehnerAm I missing something in this PR? Why are we doing two things at a time:
I think focusing on just the later one would be a more successful strategy.
Comment #21
blazey commented@dawehner see #6
Babel upgrade is not the goal of this issue, it was just a mean of making the solution work. There might be other ways of fixing it without a babel upgrade (the patch from #3047534: Allow core transpile tooling to work with files outside the default directory. maybe?).
Comment #22
wim leersWhat exactly is this postponed on? On upstream features in
babel? That was the state in #9 more than 14 months ago. Is that still true?Comment #23
blazey commentedOk, it turns out that the approach in #3047534: Allow core transpile tooling to work with files outside the default directory. is limited compared to this one. It can only process a single file and it only supports the build command, watch is not supported. Babel 7 is around for a while now so here's the updated version of #6.
Please credit @alwaysworking for the work in the mentioned issue.
Comment #25
wim leers✔
Comment #26
droplet commentedUse `cwd` I'd say.
Furthermore,
If we need more flexible, I will export the whole chokidar options (, or the Drupal script options) via Cli or config.js or both.
things like this:
https://github.com/prettier/prettier/blob/master/src/cli/minimist.js
(There're some projects structures in Drupal is a bit odd, I believe config.js, a programmable config file is more suitable for Drupal. )
Comment #27
blazey commentedThanks Wim.
@droplet we've discussed the method for passing the directory location in #5 and #6 and decided to go with the
--diras the most versatile option. For the other points, I agree a lot can be improved here. Some could even say that the javascript handling in drupal begs for improvement. Let's do one thing at a time though. This issue is about making it possible to use the current build system outside of the core/ directory. For other things please open new issues.Does anyone know what's going on with the test builds above? They are turning neither red nor green and all the build page says is
Comment #28
GrandmaGlassesRopeManI'm not sure this is the correct approach. From my perspective, this patch attempts to do too many things at once, making it quite difficult to review. If you wanted to the easiest path, excluding some limitations, to using core standards to transpile contrib JavaScript than the work in #3047534: Allow core transpile tooling to work with files outside the default directory. would have solved that problem. I'm still not sure I understand this need though.
However we've now perhaps resolved the original goal here, updated babel, and adjusted the output of all core JavaScript files. I would really suggest to break this up into a few smaller issues to make it more digestible for reviewers and committers.
Thanks.
Comment #29
blazey commentedThanks for checking @alwaysworking. This patch is actually tiny and the huge output comes from the fact that we don't use a build system and artifacts need to be committed to the repository.
Here's the breakdown of the changes:
package.jsonandyarn.lock. These are needed to get the version of babel in which the path resolution bug is fixed.babel-es6-build.js,babel-es6-watch.jsandcompile.jsare the ones that really need to be reviewed. These fit on one screen. Here's a screenshot for convenience.Comment #30
lauriiiI don't really understand why core should contain code for doing ES6 to ES5 compilation to contrib. Usually, each project should be responsible for their own tooling. I'm wondering if a better approach would be to create a separate library for our compilation process that contrib projects could depend on if they want to.
Comment #31
johnwebdev commentedFor me it would be convenient and an easy way to ensure the JavaScript I write is compliant with the Drupal standards. I must admit I had issues to even get started.
https://www.drupal.org/docs/develop/standards/javascript/javascript-codi...
States that the reasonable coding standard is 'Airbnb JavaScript Style Guide'
And then there is a separate code standard list below.
And then if we look at the Airbnb JavaScript Style Guide we can see that ES5 is deprecated which means I should probably use ES6.
So if we decide, okay, let's go ES6
https://eslint.org/docs/user-guide/command-line-interface
https://www.drupal.org/node/1955232
Following those instructions, which leads us to another problem: https://www.drupal.org/project/drupal/issues/3003522 where the suggestion is to set your own .eslintrc as root, which according to article above I shouldn't need to etc.
With that being said, all of the above could be solved by just improving the documentation and slightly and we're fine, but then again, if the contrib. module just needs some JavaScript for a change, or enhancement I'm not that keen to setup my own tooling. I just want something that works. For greater projects where JavaScript is a key of the module, sure, your own tooling makes more sense.
Yeah, this approach would also solve the DX-issues I had above.
Comment #32
blazey commentedIf you are willing to use an external tool then there's the webpack module. With webpack babel it not only transpiles the code but also makes it possible to include npm packages and takes care of the minification and bundle splitting. It can be used for core and custom libraries and provides a way to compile the ones in contrib in a way that doesn't require the webpack module to be added as a dependency. In general, it takes care of the webpack configuration and tries to make the process of bridging the JavaScript and Drupal worlds as easy as possible, while still allowing full customization through a pluggable architecture and not limiting the hosting options by supporting both commit-time and deploy-time builds. There's one problem with it though, it still seems to be hard to set up.
This issue is not about providing a perfect solution. It's about fixing a bug that makes it impossible to use a core tool in other folders. After it's fixed any drupal project will be able to use modern js with these 3 commands:
Why not just fix it?
Comment #33
blazey commentedBTW, rails 6 was released last Thursday. It comes with webpack by default https://weblog.rubyonrails.org/2019/8/15/Rails-6-0-final-release/.
At some point we might want to acknowledge the fact that JavaScript needs preprocessing. Same goes for css really. Or we can pretend they don't and just continue to party like it's 1999 :)
Comment #34
chi commentedI disagree. Browsers have made a big break in supporting ES6 and Drupal Core JavaScripts are mostly quiet simple. They are using ES6 features that are supported by all modern browsers.
https://caniuse.com/#search=es6
Once we drop support of Internet Explorer there will probably be no point to use Babel for compiling JavaScript.
Same applies to CSS. Custom properties make SASS less essential.
Comment #35
droplet commentedPreprocessor is still worth to introduce to Core. Packages like preset-env allow us to forget what we're writing for. However, for package bundlers, I think we need a proven before adding into Core. e.g.: Is it possible and how well the code splitting..etc. Personally, I don't like a mix of PHP & NODEJS code to get a simple thing work.
Second, I think when Drupal introduce these ES6 scripts into CORE, we (I) intended to make it CORE (@internal) only. At that time, I hope @internal allow the CORE JS development to move forward faster. I'm tried to see the word "BC, BC, BC". Therefore, I suggested in #26 for global configs. If we opening a hole, make everything configurable. Each option has a reason for a new patch.
In #26,
cwdis a chokidar option. We need not create another--dirand write a doc to explain how it works. Or going to figure out the difference between these options.#2658650: [META] Optimize Frontend Workflow in Core Development
Comment #36
wim leers@lauriii Very, very few contrib modules will ever figure this out. If we want contrib to follow contrib's lead/example, then we should make it feasible to do so.
I think @johndevman's comment is accurate in describing how tricky it is to follow core's example. I also struggled with it while working on https://www.drupal.org/project/entity_embed a few months ago.
Comment #37
GrandmaGlassesRopeMan@Wim Leers - I think the thing to understand is that core does things if a non-optimal way. There are original design constraints that force us to do the things the way we are currently. Contrib shouldn't feel constrained by these decisions.
Comment #38
wim leersSure. But even then it's up to core to provide guidance to contrib. If it can encourage contrib to do better than itself: wonderful! 😀🥳
Comment #39
lauriiiI think we agree that contrib is lacking proper tooling for ES6 to ES5 transpilation process. The easiest way forward would probably be creating a library that could be loaded through npm which is built without Drupal core limitations. We could also try to build proper tooling in core but that will likely take much longer. There's already some related discussion happening in #2873160: Implement core management of 3rd-party FE libraries.
I think, for now, we should say that the core ES6 compilation process is not supported beside what is needed for core since the workflow is suboptimal. As a result, we shouldn't fix bugs in the transpilation process, unless it affects core.
Comment #40
droplet commented@johndevman's comment brings out many hidden issues:
- following the CORE way to develop
- following the CORE code standard
- Disconnect from CORE
- Enable CLI to lint codes.
- Enable editor to lint codes.
- Combine core & custom setup
-- etc..
To move the package.json one level up -- The only way to get these things done perfectly. (but not the NODEJS world preferred?)
For linting, the basic step you could do now without patch:
To copy devDependencies doesn't work I think, now this doesn't specify the exact version for some packages. eg.
"^17.0.0".Or
(if you need your own package.json)
there's an installation problem on node side, you can't do it very straightly.
https://www.npmjs.com/package/eslint-config-airbnb
Comment #45
jcisio commentedFWIW, it is currently possible to use core tooling to build (not watch) custom ES6 files. For example:
However, I think there is some problem with the output (it is not really transpiled, just reformatted).
Comment #48
catchClosing as outdated now that the build step is no longer in use - contrib can just directly write ES6 JavaScript as soon as they drop compatibility with IE11.
#3278415: Remove usages of the JavaScript ES6 build step, the build step itself, and associated dev dependencies