14

I'm beginning to evaluate javascript module tools like RequireJS for javascript modularization. This seems useful, especially during development, so I don't need to recompile all of the js files into mylib-<version>.js whenever I change one of the dependent files.

My app is distributed with both html and javascript files, and in production, I would like to use the compiled version of the javascript file.

So in development, my html file might look something like

<html>
  <head>
    <script data-main="scripts/main" src="scripts/require.js"></script>
  </head>
</html>

But in production, I would expect it to look more like

<html>
  <head>
    <script src="mylib-1.0.js"></script>
  </head>
</html>

I wouldn't think it production that there should be any need to reference requirejs if I am distributing a compiled file.

Is there a way to do this without having to manually change my html files before I distribute the app?

Jeff Storey
  • 56,312
  • 72
  • 233
  • 406

2 Answers2

11

RequireJs has an optimization tool, which can help you to minify and concatenate your modules. It has a lot of options, and can be difficult to use, but it gets easier with a build tool like GruntJs or (especially) Yeoman, which uses GruntJs to build.

In both you can use the rjs task (which optimizes modules), but again Yeoman is a bit easier since it has generators which will configure it already for you:

// usemin handler should point to the file containing
// the usemin blocks to be parsed
'usemin-handler': {
  html: 'index.html'
},
// rjs configuration. You don't necessarily need to specify the typical
// `path` configuration, the rjs task will parse these values from your
// main module, using http://requirejs.org/docs/optimization.html#mainConfigFile
//
// name / out / mainConfig file should be used. You can let it blank if
// you're using usemin-handler to parse rjs config from markup (default
// setup)
rjs: {
  // no minification, is done by the min task
  optimize: 'none',
  baseUrl: './scripts',
  wrap: true,
  name: 'main'
},

In the index.html you just use a comment line to specify which js files should be minified/concatenated to which output file:

    <!-- build:js scripts/amd-app.js -->
    <script data-main="scripts/main" src="scripts/vendor/require.js"></script>
    <!-- endbuild -->

In the example above, the modules will be concatenated to ONE file, named amd-app.js.

Edit:

This will be done by executing grunt from the command line. This will start a lot of useful tasks, which will build the project in a dist folder, but again this is highly adaptable.

The resulting index.html file (in dist) has only (if you want) one javascript file:

<script src="scripts/15964141.amd-app.js"></script>

My advice: use Yeoman to make life easier (at least for handling minification/concatenation).

asgoth
  • 35,552
  • 12
  • 89
  • 98
  • If I distribute index.html with my app, it will still have a dependency on scripts/vendor/require.js though, is that correct? – Jeff Storey Jan 14 '13 at 20:42
  • No, this is the source. When Yeoman builds, it copies all to an destination folder (dist in this case). See edit – asgoth Jan 14 '13 at 20:51
  • Oh I see, so it compiles the html files as well? – Jeff Storey Jan 14 '13 at 20:57
  • It does lots of things: optimizes image files, compiles coffeescript to javascript, compiles compass to css, minification, makes a cache manifest, ... – asgoth Jan 14 '13 at 21:00
  • A feature of grunt/yeoman. You have to see it as a bundle of useful tasks (where rjs is one of them, which is the requirejs optimizer). – asgoth Jan 14 '13 at 21:05
  • Thanks, I've only used grunt for minimal things, good to know about this. – Jeff Storey Jan 14 '13 at 21:12
  • @asgoth , would you mind updating this answer with the latest since a lot of the Grunt / Yeoman environment has changed since you wrote this. Thanks for the answer even if you can't update it :) – blong Nov 04 '13 at 01:43
  • Yeoman is NOT an extension of Grunt. That's just plain misleading. It is a different tool with different purpose. – Petri Jan 27 '14 at 07:28
  • @Petri: A lot has changed to Yeoman since I've posted this answer (which i didnt follow closely due to other projects). I'll remove the misleading reference. – asgoth Jan 27 '14 at 16:42
1

First you have to compile your depency tree into one file using the r compiler. After that you can a striped down AMD loader like almond. At least you have to find a way to change the url in your index html.

Take a look at gruntjs which can automatize the whole thing, there a bunch task to like usemin that helps you with the process.

Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297