"Artificial restrictions." What qualifies as artificial?

I have not taken a good hard look at this stuff in quite some time; mundle, 
require, webmake, lot of interesting stuff.

Does any of these also do environment-specific optimization? E.g. in 
development and testing, I want all my client-side code loaded - however I 
do it: require, mundle, webmake, script tags, whatever - as is. In 
production (and maybe in beta, too, but that should be up to me), I want it 
all minified/gzipped. To my mind, the way to do it is programmatically, 
within my node app.js, have it make some call in "server.configure(env,fn)" 
wherein it will check for a cached minified/gzipped version and send it if 
there, else it will do so. But open to other ways.



On Monday, April 2, 2012 10:04:54 PM UTC+3, Saleem Abdul Hamid wrote:
>
> @deitch- 
>
> I see the problem differently. I would say that the fundamental problem of 
> a client-side module loader is exactly the same as that of a server-side 
> one:
> 1) Allow me to write really modular reusable code, without artificial 
> restrictions.
>
> The client-side module loader has a lot of domain-specific implementation 
> details that differ from the server-side. The answer to these should be to 
> hide the ones that developers can't use for their advantage, as much as 
> possible, and provide easy-to-use syntax for the ones that they can use for 
> their advantage, or really need to know about and take into consideration.
>
> Example of the first kind:
> Dynamic optimization/caching are things that we want, but shouldn't have 
> to think about
>
> Example of the second kind:
> In large web app, a developer knows as he's writing the app that some 
> thing will not happen until a user clicks something, or may never happen. 
> So never loading that code until it is needed is an advantage. In other 
> cases a certain portion of the app needs a bunch of dependencies 
> immediately, so loading them all in separate server calls doesn't make 
> sense.
>
> To handle those two cases, we have a simple syntax of synchronous vs. 
> async require statements.
>
> The examples are probably the easiest way to understand how it works.
>
> On Tuesday, March 27, 2012 4:24:07 AM UTC-7, deitch wrote:
>>
>> @meelash,
>>
>> I am pretty sure I get the basic concept, not the details, so hard to 
>> comment. 
>>
>> Let me rephrase how I understand the problem, and then maybe you can help 
>> explain how it solves it?
>>
>> On server-side, I just require(modulename) and get it. It is easy, and 
>> every module can require whatever it needs.
>>
>> On client-side, I have two problems:
>> a) Within a file, I cannot do require, the module (i.e. .js file) needs 
>> to assume whatever it needed was loaded.
>> b) I actually need to load the file separately, either through <script 
>> src="foo.js"></script> or using a loader like labjs.
>>
>> It sounds like you are trying to solve these in one fell swoop, by 
>> including one file, say <script src="specialloader.js"></src> or whatever, 
>> and having that then load all the others. However, rather than (a) fileA.js 
>> assuming the contents of fileB.js (which it needs) have already been loaded 
>> and (b) manually creating a script tag to include fileB.js, you are doing 
>> something inside fileA.js that is then parsed by a middleware on the server 
>> side? If so, how do I do it, and how do I not break the traditional 
>> client-side?
>>
>> Truth is, browsers desperately need a "require()" function, so that a 
>> script can just load other scripts...
>>
>>
>>
>>
>>
>> On Sunday, March 25, 2012 2:04:52 AM UTC+2, 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 
>>>
>>> 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 
>>> 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

Reply via email to