[wp-trac] [WordPress Trac] #28510: Split javascript files in media into modules
WordPress Trac
noreply at wordpress.org
Thu Dec 11 23:19:14 UTC 2014
#28510: Split javascript files in media into modules
-------------------------+-----------------------------
Reporter: ericlewis | Owner: wonderboymusic
Type: enhancement | Status: assigned
Priority: normal | Milestone: Future Release
Component: Media | Version: 3.5
Severity: normal | Resolution:
Keywords: has-patch | Focuses: javascript
-------------------------+-----------------------------
Changes (by wonderboymusic):
* keywords: needs-patch => has-patch
* owner: => wonderboymusic
* status: new => assigned
Comment:
[attachment:browserify.diff] breaks up the Backbone classes in `media-
models.js`, `media-views.js`, `media-audiovideo.js`, and `media-grid.js`
into CommonJS modules and injects them via Browserify on build/watch into
a built file. Let's start at the beginning.
**Brain overload**
Files that are 1000s of lines long are hard to consume. We try to
alleviate this by adding copious amounts of docs. Still, it's a lot to
look at. Ideally, we would break our files into smaller modules and then
somehow join them together in a build process.
**Require vs Browserify**
Require is a great tool for converting AMD modules into built files.
Require leans on Dependency Injection in its syntax:
{{{
define([
'model/taco',
'model/burrito',
'controller/meal'
], function (Taco, Burrito, Meal) {
var Dinner = Backbone.View.extend({
// taco-related code
});
return Dinner;
});
}}}
This syntax works great, unless you have way more dependencies.
Refactoring code could unwind a module that has a lot of dependencies, but
if you are just trying to convert legacy classes into a module, Require
starts to get a little weird.
Require becomes a Grunt task to makes one big file by recursing the
dependency tree in an initial manifest. Require, by default, loads JS
asynchronously, which can cause race conditions with plugins or themes
that expect code to be registered on `$(document).ready()` or
`window.onload`.
Require works even if you don't build via Grunt.
Browserify is a tool that allows you to use Node-style CommonJS modules
and run them in a browser without changing from the Node syntax.
Browserify requires a build for this to work.
Using our example from above, this is the syntax for Browserify:
{{{
var Taco = require( './models/taco.js' ),
Burrito = require( './models/burrito.js' ),
Meal = require( './controller/meal.js' ),
Dinner;
Dinner = Backbone.View.extend({
// taco-related code
});
module.exports = Dinner;
}}}
Browserify leans more towards the Service Locator pattern.
Browserify scans the abstract syntax tree (AST) of your JS code to compile
dependencies. Your modules themselves get wrapped in their own scope like
so: `(function(require,module,exports){ .....YOUR_MODULE..... })`.
After spending a lot of time messing around with both: I think we should
use Browserify.
**Converting "Legacy" Code**
The media JS code is some of the most "modern" code in WordPress, but it
still clunkily lives in huge files. To convert the code into Common JS
modules, we need to make a lot of individual files (one for each Backbone
class). We also need to make sure we maintain the existing `wp.media`
namespaces for backwards compatibility. We don't want any existing
functionality to change, we just want to build the files differently.
Since we are in experimentation phase, I have added a folder to `wp-
includes/js`, `media`, that contains the modules and the built manifests.
My patch adjusts `script-loader.php` to use these new paths.
`media` contains the following files/folders:
{{{
controllers/
models/
router/
utils/
views/ (with another round of subfolders)
audio-video.manifest.js
grid.manifest.js
models.manifest.js
views.manifest.js
}}}
**The build pipeline**
First things first, run `npm install`
`*.manifest.js` files get built into `*.js` files when you change a file
in `media/*`, provided you are running the `grunt watch` task. The watcher
will automatically call `browserify:media` and `uglify:media` when those
files change. This allows you to run with your site from `src` or `build`
, and you will still get Browserify'd files. `SCRIPT_DEBUG` will either
run `*.js` or `*.min.js`, just like any other minified JS in core.
**This is an experiment**
I would like us to do something like this. I got the idea yesterday to do
this proof of concept and just ran with it. Consider this a request for
comments.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/28510#comment:2>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list