Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README? #1

Open
millermedeiros opened this issue Jan 12, 2013 · 2 comments
Open

README? #1

millermedeiros opened this issue Jan 12, 2013 · 2 comments

Comments

@millermedeiros
Copy link

you mentioned the project on twitter but the README doesn't describe what the project does.

some good tips: http://tom.preston-werner.com/2010/08/23/readme-driven-development.html

@jaredhanson
Copy link
Owner

Thanks! I usually try to document projects up front, but this one was in flux
for a while as I wasn't sure the best approach to take. I wanted a sound architecture
in place before representing it as something useful, and lack of a README was a tactic
to keep people away as the architecture was undergoing some pretty drastic upheavals.

I'm just putting on the final touches now though, so I'll be doing things properly,
including a README. In the meantime, the source is well documented and here's a bit of
a preview:

The goal of JSMT is to transform JavaScript modules to AMD, so they can be loaded
via RequireJS (or similar). Right now, this transformation is primarily done via
middleware. For example, here's some code from an application I'm working on:

app.use('/js/lib', jsmt.modules(__dirname + '/../../www/js/lib'));
app.use('/js/lib', jsmt.modules(__dirname + '/../../www/js/lib-node/node_modules', { resolve: 'node', flatten: true, transitive: true }));

In this case, www/js/lib is a directory containing JavaScript modules that are
already using AMD and targeted at the browser. Among them are bosh,
xmpp, and various modules from the
Anchor.js project. (Note: AMD is optional, CommonJS
can be used and the AMD-wrapper will be applied dynamically).

The www/js/lib-node/node_modules contains modules listed in package.json and
installed via npm install. They are all in CommonJS format and target Node primarily.
Among them is Junction, which is Connect-like
middleware, but used to write XMPP applications. Despite being originally targeted at
server-side applications, the delta is negligible to make it run in a browser.

The two directories appear (to the client) as a single, "virtual" directory served at
/js/lib. The goal is to seamlessly run Node modules, such as Junction, on the client
side.

The common configuration
options for RequireJS are used to inject dependencies, replacing any browser-incompatible
modules from Node (such anything requiring TCP) with an alternative that exports the same
interface.

For example, here's a snippet of my RequireJS config:

require.config({
  baseUrl: 'js/lib',
  packages: [
    { name: 'null', main: 'null' },
    { name: 'util', main: 'util' },
    { name: 'bosh' },
    { name: 'xmpp' }
  ],
  map: {
    '*': {
      'fs': 'null',
      'node-xmpp': 'xmpp',
      'pkginfo': 'null'
    }
  }
});

In client-side JavaScript, I can now use junction as so:

require(['junction'],
function(junction) {
    var app = junction();
    app.connnect({ boshURL: 'http://127.0.0.1:5280/http-bind' });
});

The AMD loader requests junction from /js/lib/junction.js and the module is translated
from CommonJS to AMD and sent to the client. One of the dependencies is node-xmpp, which
uses TCP to connect to the XMPP network. However, in the AMD config, node-xmpp
has been mapped to xmpp, which exposes a
compatible interface but uses BOSH and Ajax as the underlying transport, such that it
works in a browser.

Under the covers, JSMT uses esprima to parse and analyze the modules
so that the AST is preserved during the transformation. The effect is similar to browserify
but admits the browser as a first-class citizen, rather than trying to port Node to the
browser (which I consider a non-starter).

For example, rather than browser-ifying modules that weren't designed for a browser (such as
net), AMD-based dependency injection is used to replace them with interface-compatible
modules that are designed for the browser. By injecting at xmpp, the net module is
never even requested by the browser.

For convenience, the Anchor.js project is providing a set of
modules conform to Node's interfaces, but are developed directly for the browser (including
things like crypto, url, events, etc.) This has been a work-in-progress for some
time, but I'll be documenting and promoting it more now that it is stabilizing. Would love
any feedback you have!

@johndvorakHR
Copy link

This is like the opposite of de-amdify

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants