[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