This seems like a really cool idea. Here are my opinions on your questions:
How to package this in a way that it can be easily used in other > projects? How can I make it integrate seamlessly with existing servers > and make it compatible with different transport mechanisms? > If you want to maximize use by others, you could make it connect middleware for portability. How to handle path resolution? You probably don't want to divulge the entire directory structure of your server, so you should probably have a root directory, which will be the "root", of where files can be included from on your server. Suggestions for licensing? > MIT is probably the most common license in the node.js community. uniquely identify clients and keep the server away of what modules > they already have, so we can just send the diff of cached modules- > currently, I'm sending the entire list of already cached modules with > every xhr call, so the server doesn't load a dependency twice. > Maybe you could you do the static analysis for dependencies on the client, so that you don't need to maintain that state on the server? Then you have the client request "/modules/my-module.js?deps=/modules/a.js:/modules/b.js" based on what it already has On Saturday, March 24, 2012 7:04:52 PM UTC-5, meelash wrote: > > tl;dr - Client-side require with a server-side component that caches > dependencies, bundles them, and caches the bundles. Need feedback on > the concept, syntax. Need suggestions/contributions on implementation. > Although, this works for me, it is almost just a proof-of-concept, > needs work. > > > As part of a project I'm working on, I spent a few hours writing a > little client-side module loader with a server-side component enabling > what I think is a pretty neat meaning to CommonJS module syntax. This > morning I pulled it out of the rest of my project and attempted to > package it in a useful way for others to use. > > The basic idea is this- in your client-side code, you can use require > in either a "synchronous" or asynchronous fashion- > module1 = require('some/path.js'); > require('some/other/path.js', function(err,result){module2 = > result;}); > > An asynchronous require makes a call to the server component to get > the file in question, but before returning the file, the server parses > it, finds all the synchronous require calls, loads those files as well > and returning the whole thing as a package. That way, when the > original file that was asynchronously loaded is executed and comes to > one of those synchronous require calls, that file is already there, > and the require is actually synchronous. > > At this point, maybe this screencast demo will help to clarify how it > works: > http://screencast.com/t/nOU53BRYUAX<http://screencast.com/t/nOU53BRYUAX> > > Put another way: > If I async require fileA, and fileA has synchronous dependencies on > fileB, and fileC, and an asynchronous dependency on fileD, the server- > side component will return (in a single "bundle") and keep in memory > fileA, fileB, and fileC, not fileD, and it will execute fileA. > The client-side also separates fetching the files and eval'ing them > (the method of getting files is xhr+eval). So, let's say fileA has > require('fileB'); that executes when the file is parsed and executed > on the client, but require('fileC') is inside a function somewhere. > Then fileA will first be eval'ed, then fileB when it comes across > that, and the text of fileC will just be in memory, not eval'ed until > that function is called or some other require to it is called by any > other part of the program. > > Another example- > fileA has dependencies fileB, fileC, fileD, fileE, fileF > fileG has dependencies fileC, fileE, fileH > > When I call require('fileA', function(err,result){return 'yay';});, > the module loader will load fileA, fileB, fileC, fileD, fileE, and > fileF all in a single bundle. > If I, after that, call require('fileG', function(err,result){return > 'yay';});, the module loader will only load fileG and fileH! > > Hopefully, that's clear.... > > The advantages- > Being aware of the difference in synchronous and asynchronous require > in your client-side code make it extremely natural to break all your > client-side code into small reusable chunks- there is no penalty and > you don't have to "optimize" later by deciding what to package > together and what to package separately. > Handling dependencies becomes nothing. You don't have to think about > it. > The server can have a "deployment" mode, where it caches what the > dependencies of a file are and doesn't ever need to parse that file > again. > In "deployment" mode, the server can also cache bundles of multiple > files that are requested together, so when another client requests > that same bundle, it is already in memory. > > To sum up: > xhr+eval-when-necessary client-side module loader > both synchronous-ish and asynchronous require in your client side-code > --the synchronous require is actually a command to the server-side > component to bundle > server-side component > --parses for dependencies and bundles them together > --can cache dependency parsing results and whole bundles > > > So- thoughts? Is this a horrible idea? Are there some gotchas that I'm > missing? > > Specific advice needed- > • How to package this in a way that it can be easily used in other > projects? How can I make it integrate seamlessly with existing servers > and make it compatible with different transport mechanisms? > • How to handle path resolution? > • Suggestions for licensing? > • Suggestions for a name- (Mundlejs is a portmanteau of Module and > Bundle- didn't really think long about it) > > Things that need to be (properly)implemented: > • server-side "parsing" is just a brittle regexp right now: > (line.match /require\('(.*)'\)/) > • neither type of server-side caching is implemented (pretty easy to > do) > • uniquely identify clients and keep the server away of what modules > they already have, so we can just send the diff of cached modules- > currently, I'm sending the entire list of already cached modules with > every xhr call, so the server doesn't load a dependency twice. > • proper compatibility with module specifications (i.e. CommonJS)- > right now, it's just require and module.exports > > > Code is available here: > https://github.com/meelash/Mundlejs<https://github.com/meelash/Mundlejs> > To test it: > from Mundlejs/tests/, run > node server.js > visit http://127.0.0.1:1337/ and open your browser console. -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to nodejs@googlegroups.com To unsubscribe from this group, send email to nodejs+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en