From: Stefan Weiss on
On 27/04/10 08:47, Garrett Smith wrote:
> Stefan Weiss wrote:
>> On 27/04/10 03:38, nick wrote:
>>> On Apr 26, 9:14 pm, Stefan Weiss <krewech...(a)gmail.com> wrote:
>>>> The next step was a
>>>> custom Perl script, which basically replicated some of the CPP
>>>> functionality, but accepted directives in a slightly different format,
>>>> and allowed leading whitespace:
>>>> //#ifdef WITH_REGEX
>>>> //#include "regexp.js"
>>>> ...
>>>> //#endif
>>> Hmm, it would be pretty easy to add that functionality with another
>>> sed before preprocessing.
>>
>> That's right. The Perl script did more than that: it also handled
>> options and preferences, paths, dependency resolution, cleanup, lint
>> checking, minification, and deployment/packaging.
>>
>> Some of the current JS frameworks (YUI, for example) have specialized
>> build systems, which can be quite complex. I don't remember any specific
>> details, but I know that some of them can be used stand-alone to build
>> other projects. Could be interesting to look at what they're doing.
>
> I have been using Ant to make custom builds. I use concat task and run
> the result through YUI Compressor. Typically I have an application js
> file and a page js file. The application file is something that most
> pages will share. That file can benefit from caching. The page js file
> is javascript something that is specific to the page.

I have used Ant for a while, too, and it works fine as a general
solution, but not so great when you're doing a lot of specialized tasks,
like filtering the output of external programs (JSLint), collecting
statistics during the build process, and creating a summary/report.
Calling JSLint and YUICompressor 100 times in a row for a full build is
also pretty slow, and I needed something I could just call whenever I
felt like it. In the Java version, both of these are embedded; a full
double lint run now takes less than 10 seconds.

> Typically I have an application js
> file and a page js file. The application file is something that most
> pages will share. That file can benefit from caching. The page js file
> is javascript something that is specific to the page.

Yes, I use a similar approach. The page js/css is often inlined (in the
HTML head or body), either explicitly, or automatically because its size
doesn't exceed a set limit.

> http://groups.google.co.kr/group/comp.lang.javascript/browse_thread/thread/c5ec3a0ee6ebc28b
>
> For some reason teh search result included Korean site for google groups.
>
> The shortcoming of that is it does not allow for runtime builds of code.
> For example, a page with a number of features, where the features used
> varies depending on http request info or stored user data.

That's something I built in from the start. It became necessary because
restarting the web app every time the JS/CSS changed was not an option:
stopping Tomcat (then sleeping and "kill 9"-ing it because it wouldn't
shut down normally), rebuilding the application, redeploying it,
restarting Tomcat - all of that can easily take 4-5 minutes, which is
completely unacceptable when you're making a lot of small changes to the
scripts or stylesheets. I needed a way to do "live" builds in a running
web app, and switch between cached and live files.

As I said, it's a pretty specialized solution, which is the main reason
why I didn't use one of the existing build systems. It does exactly what
I needed at the time, and no more. I tried to make it as generic as I
could, but until I've successfully used it in an unrelated project (and
documented it, of course), it won't be fit for release. The way things
look at the moment, that should be in September or October.


--
stefan
From: Ry Nohryb on
On Apr 27, 7:14 am, nick <nick...(a)fastmail.fm> wrote:
> (...)
> It seems like the //#instruction syntax is mutually agreed upon across
> most of the implementations I've looked at so far.

It makes sense.

$ cat build.js
//#include </Users/jorge/Desktop/assert.js>
//#include </Users/jorge/Desktop/buffer.js>
//#include </Users/jorge/Desktop/child_process.js>
//#include </Users/jorge/Desktop/crypto.js>

$ cat build.js | sed s/^\\s*\\/\\/#/#/ | cpp -E | sed s/^[#:]/\\/\\/#/
| tee raw.o.js | jsmin | tee o.js | gzip -n -9 -c > o.js.gz

--
Jorge.
From: Stefan Weiss on
On 27/04/10 18:15, Ry Nohryb wrote:
> $ cat build.js
> //#include </Users/jorge/Desktop/assert.js>
> //#include </Users/jorge/Desktop/buffer.js>
> //#include </Users/jorge/Desktop/child_process.js>
> //#include </Users/jorge/Desktop/crypto.js>
>
> $ cat build.js | sed s/^\\s*\\/\\/#/#/ | cpp -E | sed s/^[#:]/\\/\\/#/
> | tee raw.o.js | jsmin | tee o.js | gzip -n -9 -c > o.js.gz

$ cat /Users/jorge/Desktop/{assert,buffer,child_process,crypto}.js \
| tee raw.o.js | jsmin | tee o.js | gzip -9 > o.js.gz

That's what I meant when I said "I hardly ever used" preprocessor
instructions - there's usually a simpler way to do the same thing ;-)

> On Apr 27, 7:14 am, nick <nick...(a)fastmail.fm> wrote:
>> It seems like the //#instruction syntax is mutually agreed upon across
>> most of the implementations I've looked at so far.

Interesting. I had't seen it before, but I guess it's the logical choice.


--
stefan
From: Ry Nohryb on
On Apr 27, 7:09 pm, Stefan Weiss <krewech...(a)gmail.com> wrote:
> On 27/04/10 18:15, Ry Nohryb wrote:
>
> > $ cat build.js
> > //#include </Users/jorge/Desktop/assert.js>
> > //#include </Users/jorge/Desktop/buffer.js>
> > //#include </Users/jorge/Desktop/child_process.js>
> > //#include </Users/jorge/Desktop/crypto.js>
>
> > $ cat build.js | sed s/^\\s*\\/\\/#/#/ | cpp -E | sed s/^[#:]/\\/\\/#/
> > | tee raw.o.js | jsmin | tee o.js | gzip -n -9 -c > o.js.gz
>
> $ cat /Users/jorge/Desktop/{assert,buffer,child_process,crypto}.js \
> | tee raw.o.js | jsmin | tee o.js | gzip -9 > o.js.gz
>
> That's what I meant when I said "I hardly ever used" preprocessor
> instructions - there's usually a simpler way to do the same thing ;-)

Isn't she (the bash shell) lovely ? :-)

> (...) {assert,buffer,child_process,crypto}.js (...)

Hardcoding the files to build into the .sh sounds to you like a good
idea ? Agreed that this particular build.js was a dumb one, but
usually there would be much more meat into it, ifdefs, etc.
--
Jorge.
From: Ry Nohryb on
On Apr 27, 7:09 pm, Stefan Weiss <krewech...(a)gmail.com> wrote:
>
> $ cat /Users/jorge/Desktop/{assert,buffer,child_process,crypto}.js \
> | tee raw.o.js | jsmin | tee o.js | gzip -9 > o.js.gz

And maybe you should not bypass the preprocessor unless you know
beforehand that no src.js has any meat for it inside... :-)
--
Jorge.