Fork me on GitHub

Vaccine.js
?

Vaccine shot
?

Project Settings

?
Module Format (set first)
?
Support these environments
?
Project Variables

Optimizations

?
Require other modules
?
Export a module's API
?
Define an AMD module

Miscellaneous

?
Debugging
?
Variable Overrides
×

Vaccine.js - Help -

Help Start
A good introduction to Vaccine is the demo. Click the above button to see it. Also take a look at the README, particularly the FAQ, for more info.

Targets

vaccine.js

vaccine.js is the shim that makes CommonJS or AMD modules work in the browser. It includes a function to define module factories. It also implements the "require" functionality that lets a module obtain the exports from another module. Finally it provides the library as either an AMD module or a "window" global. If it defines an AMD module, it also lists dependencies.

This shim will be bundled with the rest of the modules inside an immediately invoked function. This prevents leaking any unwanted globals.

build.sh

build.sh wraps all source files including vaccine.js (at the end) inside an immediately invoked function. In the case of CommonJS, it also wraps each module individually in a "define" call, which turns each module into a factory function (closure). If it is AMD with an optional id, build.sh will also give each module an id (if one wasn't specified).

Run build.sh on the command line to produce the built file:

$ sh build.sh > my_library.js

The sources must be in a separate directory, which includes only source files. Of course, build.sh is very small, so you can extend it to fit your need.

vaccine_dev.js

vaccine_dev.js is useful when doing development. Developing with a single built file (from build.sh) is difficult, especially as libraries grow to many files. This dev version of Vaccine separates out each module in its own script tag, so finding things is easier.

vaccine_dev.js provides a requireDev function that by default will give the exports of the main (entry) file. Specifying a module id as the only parameter will give the exports of that module.

Below is an example of how vaccine_dev.js is used

<!-- Must be before sources -->
<script src="/vaccine_dev.js"></script>

<!-- Sources can be in any order -->
<script src="/src/underscore.js"></script>
<script src="/src/underscore/arrays.js"></script>
<script src="/src/underscore/collections.js"></script>
<script src="/src/underscore/each.js"></script>
<script src="/src/underscore/functions.js"></script>
<script src="/src/underscore/objects.js"></script>
<script src="/src/underscore/utils.js"></script>

<!-- Get the main exports with "requireDev()" -->
<script>var _ = requireDev();</script>

Note that in order for the script tags to work with CommonJS, a development server is needed to wrap the modules in "define" calls. AMD does not have this problem.

dev_server.js

dev_server.js is a simple development server that serves up static files from the project's root directory. It will also wrap CommonJS modules under the source directory so that they can work in a script tag.

To use the dev server, copy down dev_serve.js to your project. This server uses Express on top of Node.js. With Node.js installed, install express with: npm install express.

Run the server with $ node dev_server.js

The other functionality in the server is being able to run build.sh and having the results used in a script tag with href set to "build.sh". In fact any file with a path that starts with "build" will be executed before returning the results.

Makefile
A barebones makefile that saves a bit of typing so that sh build.sh > my_library.js can just be make.
umd.js

Project Settings

Module Format
To use Vaccine, the JavaScript files must be written in one of the following three module formats. Set the module format before any other options are set, since it will hide options that don't work with the chosen format. Clicking the buttons will also set all options back to the default.
  • AMD - How AMD works. AMD requires a build step with sh build.sh > library.js. An AMD module is written with a call to define. Currently, the supported method signature is define(id?, factory). The factory parameters are factory(require, exports?, module?) with the last two depending on the exports configuration.
  • CommonJS - How CommonJS works. CommonJS requires a build step with sh build.sh > library.js. The format is very similar to the inside of the factory of an AMD module. There are three free variables: require, exports, and module.
  • UMD - How UMD works. UMD is a pattern for a single file to support multiple environments, such as CommonJS, AMD, or a regular browser global. It does not need a build.
Environments Supported
These options determine what environments the project will support. Some formats cannot work in some environments, so they will be marked in red.
  • Global (window) - This is the standard method of creating a single global variable for a library (or application). Then, any code that uses this library will have access via the global variable.
  • AMD - This option means that the library will work in any application that uses an AMD module loader, such as RequireJS. That is, this option adds a define('library_name', factory) if AMD is detected.
  • CommonJS - This option means that the project will support CommonJS environments, such as Node.js.
Project Variables
These variables are used to configure the shim to work for the project.
  • Name - The name of the project. The global variable as well as the AMD module id will be set to this.
  • Dependencies - The names of the library's dependencies. This will be used if supporting an AMD environment, with the define call.
  • Main (entry file) - The relative path of the main file from the project's root directory. For built libraries (AMD, CommonJS), all the source files must be in a separate directory with only sources. This source directory is extracted from the path to the main file, but can be overwritten with a variable override.

Optimizations

Require
The require options set how a module will obtain the exports from a module it depends on. For example, assuming a source directory of "src", the "src/a.js" module could get the exports from "src/b.js" by doing a var b = require('./b'). Note the lack of a ".js" at the end of the id string. This must be left out to work. Certain projects have only one level of code, which means they can use simpler "require" functionality.
  • full relative - A full "require" implementation that supports complex relative require's such as require('../../module.js'). It also supports a single relative or absolute id, which is why those options don't do anything when this one is checked.
  • single relative - A simple single directory require of the format require('./{{module}}'). This means a file at "src/a.js" could require "src/b.js" with require('./b'), but it wouldn't be able to require "src/some_dir/c.js" with just this option checked. See the extra optimization at the end of the "absolute id" section.
  • absolute id - Require a module with the full AMD path (which doesn't include the source directory). For example, the "src/my_lib.js" file could require "src/my_lib/utils.js" with require('my_lib/utils'). Note the lack of a "./" or "../" at the beginning signifying that this is an absolute path. This option is only available to the AMD format.

    An extra optimization can occur if an AMD project has "single relative" requires only in files immediately under the directory of the same name as the project, and "absolute" requires everywhere else. The optimization is to use only "absolute" and "single relative" options, and the single relative requires will be translated into absolute ones by replacing the dot with the name of the project.

  • w/o index - This means that the "/index" is left off the end of requiring an "index.js" module. So, for example, module "src/foo.js" must require "src/utils/index.js" with require('./utils'). Note that the module can not also be required with the "/index" at the end, so beware. This only works for CommonJS format with a full relative implementation.
Exports
The export options decide how a module can export its API.
  • exports - Export via attaching properties to the exports object (free variable for CommonJS; second factory parameter for AMD). A module can export a "foo" method via exports.foo = ... . The exports object becomes the module's API.
  • module.exports - Export via setting module.exports with the module's API. If, for example, "bar.js" wanted to have a function as the API, it could module.exports = function() .... Then, another module could var bar = require('./bar'); ... bar() to run the function.
  • return - Export the API via returning an object from the AMD factory. This only works for AMD.
Define
This section is AMD only. It sets how the "define" call operates.
  • optional id - This option makes it possible to leave out the module id in the "define" call, so: define(factory). It makes the build step (build.sh) slightly more complex, but saves some typing. When unchecked, the module id must be included: define(id, factory).
  • array - This option hasn't been implemented yet, but is there to signify that the dependency array in the "define" call is not supported.

Miscellaneous

Debugging
These options add some helpful debugging.
  • debug - Logs different actions to the console, such as when a module is defined or required. It also throws an error if a module is redefined, or required but never defined.
  • performance - Calculates the time it takes to define all the modules and run their factories.
  • "use strict"; - Adds a "use strict" into the built library to enable strict mode.
Variable Overrides
These options override the settings derived from the project variables.
  • Source directory - Sets the source directory used in "build.sh".
  • Global variable name - Sets the name of the global variable when supporting that environment.
Controls
These controls add the ability to save or compare different shim configurations.
  • Save - Remember the current configuration as a "saved" version of the shim. Multiple presses will overwrite the saved version.
  • Swap - Swap the current configuration with the one that is saved.
  • Diff with saved - Do a "diff" between the current configuration and the saved configuration. Red lines are lines the current configuration removed. Green lines are lines added in the current shim. Black ones are in both. Also notice that the sizes report the difference between the two.
Size Info

When in Diff mode, the numbers are the difference between the configurations under comparison. When red, the current configuration is smaller (showing bytes removed). When green, the current configuration is larger (showing bytes added).

The bytes minified are calculated by running UglifyJS on the text of vaccine.js wrapped in an immediately evaluated function (function() { ... }()).

Gzipped size was calculated by gzipping various vaccine.js versions with a 4.8k sized library. A linear regression fit the resulting gzipped sizes with a 0.997 correlation coefficient. Note that when compressing with smaller libraries, the amount added tends to be more.

Vaccine makes it easier to develop JavaScript libraries. Specifically, it permits a library to use CommonJS (Node.js) or AMD module formats and still work in both browser and server. (These formats try to remedy JavaScript's lack of modules, so using them produces more modular code. Read more about these formats here.) Vaccine works by generating a small shim that gets built with the project's code into a single file that works in a script tag.

The shim is configurable, which decreases its size by including only the required functionality. Some libraries need to work in both server and client, and Vaccine makes it easy for them to do so. Now the library can be written in the server's native CommonJS format and still work in the browser. The tiny size of the shim makes this feasible for the many small JavaScript libraries.

The best example of reducing size via configuration is for projects that have only one directory of source files (no subdirectories). Having one level of sources simplifies the require implementation considerably.

To use Vaccine, either use the GUI you see here or the build tool described in the README. The GUI makes it easy to see how Vaccine works, but the tool can automatically detect options that have to be manually set with the GUI. To use the GUI, first set the options in the left panel. The shim will instantly adjust to changes. The help icons will be a good resource.

All options can be selected in any combination. However, certain combinations of options do not work, and are marked in red. A fix it link can be used to correct the problem.

Set the project's module format and then choose what environments the project will support.

Enter your project's name, main file, and dependencies to make the shim work for your project.

Optimize the shim size by checking only the necessary functionality.

Use the diff button to compare between the current and saved configuration. The size shows the amount added or removed.

After setting the options as desired, copy vaccine.js and build.sh to your project's root directory. When you are ready to build, run sh build.sh > my_built_file.js. Note that all source code, and only source code, must be in a separate directory for the tiny build script to work.

Use the UMD format for single file projects—no build required.

For development, the vaccine_dev.js version can be placed before script tags for all the modules (in any order). Call requireDev() to get the project's global.

The name "vaccine" comes from the analogy that the shims are injected into the code like the virus used in a vaccine, and that they are a temporary treatment until the Harmony modules "cure" arrives.

For help with any of the options, and for other info, view the help document. Also see the README and FAQ for more info.

Diff with saved
?
?