I have been fiddling with require.js for the last couple of days. It really takes some effort to get started with, but seems to bring enough power to the table to make it worth the bother. Last night, for instance, I was able to figure out how to bundle my all the Javascript in me Backbone.js (backbone.js, jquery.js, etc) into a single, "built" Javascript files. That would certainly be quite powerful for deployment.
Tonight, I hope to build on that effort to not only build the the Javascript, but update all of my HTML such that it references the proper, built Javascript file. Currently, my node.js based application is laid out as:
. ├── app.build.js (require.js build configuration) ├── app.js (node.js server) └── public ├── index.html └── scripts ├── app.build.js ├── backbone.js ├── jquery-1.7.1.js ├── main.js ├── my-calendar │ ├── routers │ │ └── paginator.js │ └── views │ └── paginator.js ├── my-calendar.js ├── require.js └── underscore.jsTo generate an optimized version of my backbone application, my
app.build.js
file contains the following:({ // Where my HTML and JS is stored: appDir: "public", // Top-level directory containing my JS: baseUrl: "scripts", // Filename containing my top-level requirejs application: name: "main", // Destination of the optimized version of my application: out: "public-build/scripts/main.js", // Resolve any 'jquery' dependencies to the versioned jquery file: paths: { 'jquery': 'jquery-1.7.1' } })When I use that to optimize from my application directory (one level above the
public
sub-directory containing my backbone app), I get:➜ backbone-requirejs-test git:(master) ✗ ./node_modules/requirejs/bin/r.js -o app.build.js Tracing dependencies for: main Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/main-built.js /home/cstrom/src/backbone-requirejs-test/public-build/scripts/main.js ---------------- /home/cstrom/src/backbone-requirejs-test/public/scripts/jquery-1.7.1.js /home/cstrom/src/backbone-requirejs-test/public/scripts/underscore.js /home/cstrom/src/backbone-requirejs-test/public/scripts/backbone.js /home/cstrom/src/backbone-requirejs-test/public/scripts/my-calendar/views/paginator.js /home/cstrom/src/backbone-requirejs-test/public/scripts/my-calendar/routers/paginator.js /home/cstrom/src/backbone-requirejs-test/public/scripts/my-calendar.js /home/cstrom/src/backbone-requirejs-test/public/scripts/main.jsThe result is a 120k main.js file:
public-build └── [4.0K] scripts └── [119K] main.jsThat 120K comes from my application code (main.js, my-calendar.js, etc) as well as library code (jquery, backbone, etc.):
public ├── [ 416] index.html └── [4.0K] scripts ├── [ 106] app.build.js ├── [ 42K] backbone.js ├── [242K] jquery-1.7.1.js ├── [ 140] main.js ├── [4.0K] my-calendar │ ├── [4.0K] routers │ │ └── [1.0K] paginator.js │ └── [4.0K] views │ └── [ 938] paginator.js ├── [ 379] my-calendar.js ├── [ 79K] require.js └── [ 34K] underscore.jsThat seems to be working well enough, but how might I go about deploying this? I could have a post-optimize script that copies the built "main.js" over top of the original version. That is a pain, though.
Thankfully require.js has a mechanism for dealing with just this situation. In the optimization documentation, this is referred to as "whole project" optimization. What this does is copy over the entire
appDir
to another location, overwriting the main "module".To accomplish this, I have to remove the "name" and "out" configuration options from
app.build.js
. Instead, I specify the name of the output directory with out
and the name of the module being optimized with the modules
option:({ // Where my HTML and JS is stored: appDir: "public", // Top-level directory containing my JS: baseUrl: "scripts", // Where to build the optimized project: dir: "public-build", // Modules to be optimized: modules: [ { name: "main" } ], // Resolve any 'jquery' dependencies to the versioned jquery file: paths: { 'jquery': 'jquery-1.7.1' } })Now, when I run the optimizer, I get:
➜ backbone-requirejs-test git:(master) ✗ ./node_modules/requirejs/bin/r.js -o app.build.js Tracing dependencies for: main Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/my-calendar/views/paginator.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/my-calendar/routers/paginator.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/jquery-1.7.1.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/main.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/require.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/underscore.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/app.build.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/backbone.js Uglifying file: /home/cstrom/src/backbone-requirejs-test/public-build/scripts/my-calendar.js scripts/main.js ---------------- scripts/jquery-1.7.1.js scripts/underscore.js scripts/backbone.js scripts/my-calendar/views/paginator.js scripts/my-calendar/routers/paginator.js scripts/my-calendar.js scripts/main.jsHrm... I could do without the copying / uglifying of the various library files. Still, it does seem to have copied over both the HTML and the optimized
main.js
:public-build ├── [ 219] build.txt ├── [ 416] index.html └── [4.0K] scripts ├── [ 77] app.build.js ├── [ 14K] backbone.js ├── [ 92K] jquery-1.7.1.js ├── [119K] main.js ├── [4.0K] my-calendar │ ├── [4.0K] routers │ │ └── [ 725] paginator.js │ └── [4.0K] views │ └── [ 679] paginator.js ├── [ 225] my-calendar.js ├── [ 14K] require.js └── [ 11K] underscore.jsBest of all, I only need point my node application to this
public-build
directory to serve up my Backbone application all bundled into a single main.js
:I think that about does it for optimizing with require.js. Up tomorrow: converting my existing Backbone app to use require.js
Day #226
No comments:
Post a Comment