#28510 closed task (blessed) (fixed)
Split javascript files in media into modules
Reported by: | ericlewis | Owned by: | wonderboymusic |
---|---|---|---|
Milestone: | 4.2 | Priority: | normal |
Severity: | normal | Version: | 3.5 |
Component: | Media | Keywords: | has-patch |
Focuses: | javascript | Cc: |
Description
Yesterday in dev chat, ideas for splitting up distinct javascript modules in were discussed. As we move towards more and more javascript-heavy administrative interfaces, this will prove quite helpful in readability, and by extension maintainability. A 6000 line file made up of 50-some views is not easy to step into. A folder of well organized modules for one feature would be.
This will only affect the src/ directory in the develop repository, which will use our build process to concatenate into the build/ directory, so nothing will change for developers using the build/ directory or the core repo.
We'll start this effort with media, and end up with a standardized way of doing this going forward.
Attachments (15)
Change History (56)
#1
@
10 years ago
- Keywords needs-patch added
- Milestone changed from Awaiting Review to Future Release
#2
@
10 years ago
- Keywords has-patch added; needs-patch removed
- Owner set to wonderboymusic
- Status changed from new to assigned
#3
@
10 years ago
options: { debug: true, keepAlive: true, watch: true }
for the browserify
task seems to be a lot faster than adding it to the watch
task.
#5
@
10 years ago
Creating /controllers/states/
and /controllers/frames/
folders might be helpful, since we have a bunch of both.
#10
@
10 years ago
Above patch adds newlines at the end of all the files, and removes some trailing whitespace.
#12
@
10 years ago
Same, but with updated bundle. A con of browserify is that is bloats patches... :( But necessary if we want trunk to be runnable...
#13
@
10 years ago
I removed the "debug" option for now, because that doesn't do anything. If we want that, we need to add it under browserifyOptions
. But patches should never be uploaded, or committed, with that option. It adds the absolute path to all the files, which is different for everyone of course. Not sure how we should solve this. Normally you don't version control the built files. When "watching", we could add that option, but before uploading the patch the contributor should run browserify without it.
#14
@
10 years ago
About the watch task. Imo we should really use Browserify's build in "Watchify". It's a lot faster because it caches previous work. Just running grunt watch:browserify
on my computer takes about 80s each time a file changes. This would need to be a separate watch task though. You can still add the grunt watch task after it and do more stuff, and leave out the keepAlive
option for Browserify.
I'll wait to make a patch, don't want to make a huge patch combining the previous one.
#17
@
10 years ago
Here's what the Gruntfile could look like with Watchify. You can run grunt watchify
to watch all browserify bundles (I had to split them, I couldn't get it to work otherwise). The last task is kept alive, but you can just as well use grunt watch
for that. You can watch the Browserify bundles (instead of the modules themselves) to run any tasks after Browserify did its thing (e.g. uglify).
I also added browserify
to the precommit
task so you can use it to remove debug information.
#33
@
9 years ago
- Resolution set to fixed
- Status changed from assigned to closed
I'm going to mark this as fixed. New tix for no problems.
#34
@
9 years ago
I am the author of Media Library Assistant, a plugin that adds some features to the Media Manager Modal Window. I have struggled with earlier versions of the media JS code and I am happy to see these improvements. However, the 4.2 beta completely breaks my plugin and I am at a loss on how to modify my code to support the new version. Where can I go to find the "right" way to, for example, add a control to the toolbar or to replace the existing search box with an enhanced version? If there is a better place to ask this question, let me know. Thanks for any help you can provide.
#35
@
9 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
Oh man - I will take a hard look and see what is necessary here
#36
@
9 years ago
Thank you for your instant response! Let me be clear - I am all in favor of the improvements you've made and I know it's my responsibility to update my code to conform. I admit my JavaScript, etc. skills lag my PHP skills and my current Media Manager support is a hack; I just want to know how to do the right thing.
By the way, my code still runs fine (mostly) with the Media/Library grid view, but it fails completely in the popup "Add Media" modal window.
Thanks again for your consideration.
#37
@
9 years ago
Testing out Jetpack's Tiled Galleries (which adds a menu to the Create Gallery modal), that is also no longer displaying.
browserify.diff breaks up the Backbone classes in
media-models.js
,media-views.js
,media-audiovideo.js
, andmedia-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:
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()
orwindow.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:
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 adjustsscript-loader.php
to use these new paths.media
contains the following files/folders:The build pipeline
First things first, run
npm install
*.manifest.js
files get built into*.js
files when you change a file inmedia/*
, provided you are running thegrunt watch
task. The watcher will automatically callbrowserify:media
anduglify:media
when those files change. This allows you to run with your site fromsrc
orbuild
, 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.