[wp-trac] [WordPress Trac] #40834: Introduce a JS module pattern to WordPress
WordPress Trac
noreply at wordpress.org
Mon May 22 10:25:35 UTC 2017
#40834: Introduce a JS module pattern to WordPress
-------------------------+-----------------------------
Reporter: omarreiss | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version:
Severity: normal | Keywords:
Focuses: |
-------------------------+-----------------------------
This is a discussion ticket proposing an approach for implementing module
pattern in WordPress core JavaScript.
== Introduction to modules. ==
For anyone reading this and wanting to learn about JS modules,
[https://twitter.com/iam_preethi Preethi Kasireddy] wrote an excellent two
part introduction. You can find it here:
* Part 1: [https://medium.freecodecamp.com/javascript-modules-a-beginner-s
-guide-783f7d7a5fcc about what modules are and why you should use them.]
* Part 2: [https://medium.freecodecamp.com/javascript-modules-part-2
-module-bundling-5020383cf306 about module bundling and the different ways
in which that can be done.]
== Goals ==
The higher level concerns that I based this on are:
* The need to modularize our JS in order to make it more maintainable,
robust and reusable.
* (Backwards) compatibility with current state and
{{{wp_register_script}}} / {{{wp_enqueue_script}}}.
* Great developer experience.
* Allowing core to take advantage of the rich npm ecosystem and current
day ES standards.
* Lowering the barrier for the greater JS community to participate in
WordPress.
* The benefit of aligning ourselves with [https://github.com/Automattic
/wp-calypso Calypso] as much as possible.
== Module definition ==
Currently in core modules are only being used in the WP media library,
which follows Common JS module definition,
[https://core.trac.wordpress.org/ticket/28510 see modularization ticket].
I would however prefer to switch to ES6 module definition as this is where
the JS world is moving and [https://caniuse.com/#feat=es6-module most
browsers seem to be working on adding support] as well. Another thing to
keep in mind is that Calypso is also using ES6 module imports.
I think it should be a priority for us to align with ES standards as much
as possible, especially since transpilers like
[https://github.com/babel/babel Babel] and different available polyfills
have already solved all major browser compatibility problems for us.
Embracing the latest (widely adopted) practices will also help open up
WordPress as a project to the greater JavaScript community.
== Module bundler ==
The current bundler of choice is [http://browserify.org/ Browserify]. The
other options are [https://github.com/webpack/webpack Webpack] and
[https://rollupjs.org/ Rollup].
Webpack is currently the weapon of choice in most React projects. I think
this is especially because the development experience is very enjoyable
due to its hot reloading capabilities and its ability to only recompile
the module that has been changed instead of rebuilding the entire build
every time. This is especially great for developing single page apps. As
developers we could take advantage of these features as well if we add
some code that allows the scripts to come from a different server. This
would also be very useful for production as I think it makes a lot of
sense to serve our JS from a CDN in the future.
The React project itself has [https://github.com/facebook/react/pull/9327
recently switched from Browserify to Rollup]. By using a technique called
[https://rollupjs.org/#tree-shaking tree shaking] it's able to
dramatically reduce file size of the bundle. It's also possible to include
as a [https://github.com/egoist/rollup-loader Webpack plugin] or
[https://github.com/nolanlawson/rollupify Browserify transform].
Here's a [https://medium.com/@housecor/browserify-vs-webpack-b3d7ca08a0a9
good article comparing Browserify and Webpack].
I would prefer to switch to Webpack, especially if we can make the
developer experience as smooth as not having to reload pages anymore to
see changes directly reflected in the browser. The fact that Calypso is
also using Webpack is also a big plus.
== How can we go about bundling the JavaScript in core? ==
Taking into account backwards compatibility, once a script has been
registered in core, it can not be removed. Plugin and theme authors
unregister / replace scripts or enqueue scripts that aren't enqueued by
core on certain screens. Therefore I'd say we might have a bundled file
for every script that is currently registered in core. Anything that is in
a registered script can of course be extracted away into a separate
module. This will give us a ton of freedom as modules can be rearranged
without having to worry about bc.
== What are the implications on current API's? ==
Anything that needs to be on the global {{{wp}}} object could still be
assigned to it. However, using modules should eventually lead to better
composition. Modules that don't need to know about global API's shouldn't
depend on them or assign themselves to global objects. I believe it's
possible to configure Webpack to do these assignments for us. Of course
it's always possible to do it in a separate file.
== Do we need to move everything into modules straight away? ==
No, modularizing code is typically something that can be gradually
implemented. We just need to agree on the direction so we can build a
roadmap and start implementing it. I do think we need to document our
decisions well and make sure core is in sync with that. It will be highly
beneficial to have good examples in the code itself of how things can be
modularized. There might also be a few things which we simply don't want
to modularize, like jQuery for instance, since jQuery needs to be globally
available anyway for bc reasons. I am curious to see opinions about this
since there could be architectural reasons to still do this.
== Do all modules we for core need to reside in core? ==
I would very much like all general purpose modules to be extracted to a
separate package on which core depends. We are an open source project. If
we can organize our code in a way that makes it more reusable for the
greater community of developers, we should do so. Anything core specific
should of course reside in core.
Using modules in core will also expose endless new possibilities in terms
of depending on third party libraries / modules. This is another great
opportunity if you ask me to build stronger ties with the greater JS
community.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/40834>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list