Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/kriszyp/transporter

Transporter is JSGI application that serves modules to the browser with dependencies included and packaged in the CommonJS module transport format.
https://github.com/kriszyp/transporter

Last synced: 21 days ago
JSON representation

Transporter is JSGI application that serves modules to the browser with dependencies included and packaged in the CommonJS module transport format.

Awesome Lists containing this project

README

        

Transporter is a JSGI appliance that serves modules to the browser with dependencies
included and packaged using the CommonJS asynchronous module definition API:

[wiki.commonjs.org/wiki/Modules/AsynchronousDefinition](wiki.commonjs.org/wiki/Modules/AsynchronousDefinition)

This format permits asynchronous loading of modules and combining multiple modules
(modules with their dependencies) into single responses. Transporter should work
with any client side module loader that supports the CommonJS module transport
format. This has been primarily tested with RequireJS and Yabble:

[http://github.com/jrburke/requirejs](http://github.com/jrburke/requirejs)
[http://github.com/kriszyp/yabble](http://github.com/kriszyp/yabble) (currently the kriszyp fork is needed because of some implementation bugs in define handling in Yabble)

To use transporter, include the appliance in your JSGI stack:

var Transporter = require("jsgi/transporter").Transporter;
exports.app = Transporter();

Now you can use a client side module loader like RequireJS, Yabble, or the simple loader
that comes with transporter to load your modules:


If my-module.js requires other modules (using a require call), these modules will
automatically be included in the request for my-module.js (multiple requests are not
needed). This is all that needs to be done to load CommonJS modules. With this
mechanism, the easiest way to included a set of modules is to create a module that
requires all of them, and load it with a script tag.

We can also specify a set of modules with the path we provide to the script tag. The
module names can be comma separated:

Dependency Control
------------------

There may be situations where you want a certain module (or set of modules) is used
on several pages, but other modules are unique to that page. In such situations it can
be advantageous to two separate script requests, so that one script request/response can be
cached for later visits to other pages that will reuse that set of modules, and another
script request can be used for page-specific modules. This can also be using transporter's
negation syntax. If a module name is prefixed with a dash, this will indicate that the
module and it's dependencies have already been loaded and should not be included
in the given response. For example:




RequireJS provides additional facilities for asynchronously loading of modules
which can be very useful for loading modules on demand.

Configuring Transporter
----------------------

The Transporter appliance can also be configured to support different scenarios.
The first parameter is the options, which can have several properties (they are all optional):

* url - The URL path prefix for all the javascript libraries that will be processed by the Transporter. This defaults to "/lib/".
* loader - A function to be called to load a module. This is called with a module id and
should return the source of the module. If you are using nodules, you can
conveniently reuse the current package and mapping configuration with the browser,
(and utilize the browser overlay for browser-specific modules):

loader: require("nodules").forEngine("browser").useLocal().getModuleSource,

* resolveDeps - A boolean that indicates whether the dependencies of a module should be included
in the response to the client (or if the client should request each dependency). This defaults
to true.
* autoRun - A boolean indicating whether the module should automatically be executed
on the browser. Defaults to true.
* converter - You can specify alternate wrapping mechanisms with the converter
property. The value of converter can be one of the converters exported by the
transporter module:
** CommonJS - CommonJS module transport format (Transport/D). This is the default.
** CommonJSTransportC - CommonJS module Transport/C.
** Dojo - For Dojo modules
** DojoRequireJS - For Dojo modules with use with RequireJS
For example:

require("transporter").Transporter({
converter: require("transporter/jsgi/transporter").CommonJSTransportC,
...

* paths - The set of paths to lookup modules in. The defaults to require.paths set of
paths where any /engines/some-engine paths replaced with a /engines/browser path.
This is only be used if no "loader" property is provided.

The second parameter is next JSGI application, so Transporter can be used as middleware.

For example:

require("transporter").Transporter({
urlPrefix:"/js/",
paths: ["/some/path"]
}, nextApp);

Using RequireJS
----------------

You can use require.js to load your modules (of
course you should actually download transportD-require.js for local access):


// Configure RequireJS
require = {baseUrl: "lib/"};


Using Yabble
------------

Using and configuring Yabble looks something like this (once again, you should use your
own copy):



// Configure Yabble
require.setModuleRoot("lib/");
require.useScriptTags();

Including Module Loader
-----------------------

If two requests for modules (one for the module loader and one for the actual module)
is too many, we can actually include require.js or yabble.js in our module. For example:

my-module.js:

require("require"); // this will cause require.js to be included
require("module-a");
require("module-b");

Now we can simply include a single script tag, and require.js, module-a.js, and
module-b.js (and any dependencies they have) will be included in the response for
my-module.js.