Actually, modules-webmake looks pretty cool. I am still trying to wrap my
head around it, and how it is different than labjs or any of the other
loaders, or browserify or other converters.
So, I would write code in the CommonJS style, but have it available to the
browser? I still need to write for the browser (jQuery, DOM, non-V8
limitations, etc.), but rather than *assuming* I have stuff in, say,
APP.utils.foo, I could just do
var foo = require('./util/foo');
and this would do the right thing, and render it up for the browser to use?
I could see how the programmatic might be useful. I add a line:
<script src="/myassets.js"></script>
then have expressjs intercept it, run Webmake, then minify and gzip the
source. To prevent redoing, it could cache the result in memory or even on
disk. If it exists, serve it out; if not, Webmake+minify+gzip and serve it
out.
Q: does this have any impact on browser render times? This takes all 100+
files and makes them a single file, as opposed to loading multiple in
parallel.
Cool.
On Tuesday, March 27, 2012 10:34:34 AM UTC+2, Mariusz Nowak wrote:
>
> Guys, check https://github.com/medikoo/find-requires
>
> --
> Mariusz Nowak
> https://github.com/medikoo
> http://twitter.com/medikoo
>
> On Tuesday, March 27, 2012 10:26:32 AM UTC+2, Bruno Jouhier wrote:
>>
>> Same way you do it: regexp
>>
>> On Monday, March 26, 2012 9:49:28 PM UTC+2, meelash wrote:
>>>
>>> btw, bruno, how do you do the dependency analysis? A full parser?
>>>
>>> On Monday, March 26, 2012 12:01:41 AM UTC-7, Bruno Jouhier wrote:
>>>>
>>>> I have a similar thing. Not fully packaged but I published it a while
>>>> ago: https://github.com/Sage/streamline-require
>>>>
>>>> It analyzes the dependencies server side and supports both synchronous
>>>> and asynchonous requires. Like yours, it returns the entire dependency
>>>> graph in one shot. So the client gets everything it needs in one
>>>> roundtrip.
>>>> It also monitors changes to the source tree and returns a 304 if the
>>>> browser has an up-to-date version.
>>>>
>>>> There is one further refinement: when you request additional module
>>>> asynchronously, the client sends to the server the list of modules that it
>>>> had requested before and the server computed the list of dependencies of
>>>> the new modules as well as the list of dependencies of the modules that
>>>> had
>>>> been requested before and it sends back to the client a single response
>>>> with the modules of the first list that are not in the second list. So, if
>>>> the client had gotten A, B, C, D, E, F in a first require and requests G
>>>> which requires B, C, and H, the server only returns G and H to the client.
>>>> I the client then requests I which requires C, F and H and J, the server
>>>> returns only I and J.
>>>>
>>>> Overall, this is extremely fast.
>>>>
>>>> I was doing the dependency analysis client side before and loading the
>>>> modules one by one. Terrible in comparison.
>>>>
>>>> Bruno
>>>>
>>>> On Sunday, March 25, 2012 1:04:52 AM UTC+1, 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en