views:

2751

answers:

6

Hello,

I want to create a compiled JavaScript file for my website. For development I would prefer to keep the JavaScript in separate files and just as part of my automated scripts concatenate the files into one and run the compressor over it.

My problem is that if I use the old DOS copy command it also puts in the EOF markers which the compressor complains about:

copy /A *.js compiled.js /Y

What are other people doing?

+4  A: 

To copy without EOF use binary mode:

copy /B *.js compiled.js /Y

If the resulting file still has EOFs, that might have come from one of original files, it can be fixed by this variant:

copy /A *.js compiled.js /B /Y

/A removes trailing EOFs from original files if any and /B prevents appending EOF to the resulting file. If an EOF is not at the end, the source file will be truncated at it. The order of switches is important. If you write

copy /A *.js /B compiled.js /Y

- EOFs in source files won't be removed but still resulting EOF won't be appended.

Try it yourself, thats where I get it. DOS commands are weird.

eugensk00
Oddly the /B option made no difference to my files
Phil Hannent
I tried your suggestion, however I still get:As a marker between where the files join...thanks for looking at this.
Phil Hannent
It seems I got it,  is a UTF8 prefix bytes. It should be at the very beginning of file, othervise it is treated as data and your compiler complaints on it. It is not EOF problem. And you can not use copy.
eugensk00
Thank you for your time eugensk00
Phil Hannent
+2  A: 

We have created a mechanism consisting of the following parts:

  • minfication (for js and css)
  • aggregation in packages
  • caching (http status 304 stuff)
  • sending out original files for in development mode

It may be too much for your needs, but as to answer your question what others do, here is how it works:

  1. A request comes in at, say, /css.aspx?package=core
  2. We do a lookup of the packagename in a xml configuration file (which for instance declares that the package "core" contains the files /js/mootools.js and /js/swfobject.js)
  3. We check if minification is enabled. For instance, in a development environment we don't want the minified js contents to be served out, but instead write the original files. For js this is done by document.writes of script includes, and for css we write import rules.
  4. If minification is required (in production env) we do a check on the if-modified-since header from the request. If this client already has the minified contents, we send http header 304. If the client does require the contents, we check if we have minified contents in cache and serve that. Otherwise, we minify and send the result.

All this is broken up in separate services. There is a cache service injected in the jsminificationwriter service. This makes use of the original minificationservice that solely takes care of the minification rules.

What's nice in this approach is:

  • It forces our development teams to think in js/css "packages" and therefore properly split up functionality and distribute them over the pages that require them.
  • During development you are perfectly able to debug, getting proper files and line numbers.
  • You can hook up any other minification service implementation such as YUI and so forth. JsMin was only our first take.
  • It's a general approach that works for different content types.

Hope this helps. I can post some code fragments to illustrate it more if you like.

Martin Kool
A: 

You can also do:

type *.js > compiled.js
PhiLho
There must be something strange with my setup as type gives exactly the same marker as the copy method does:
Phil Hannent
BOM? Are your files ANSI or UTF?
GalacticCowboy
+6  A: 

I recommend using Apache Ant and YUI Compressor.

http://ant.apache.org/

http://www.julienlecomte.net/yuicompressor/

Put something like this in the Ant build xml. It will create two files, application.js and application-min.js.

<target name="concatenate" description="Concatenate all js files">
    <concat destfile="build/application.js">
        <fileset dir="src/js" includes="*.js" />
    </concat>
</target>

<target name="compress" depends="concatenate" description="Compress application.js to application-min.js">
    <apply executable="java" parallel="false">
        <filelist dir="build" files="application.js" />
        <arg line="-jar" />
        <arg path="path/to/yuicompressor-2.4.2.jar" />
        <srcfile />
        <arg line="-o" />
        <mapper type="glob" from="*.js" to="build/*-min.js" />
        <targetfile />
    </apply>
</target>
David Brockman
+1  A: 

I'll second yuicompressor, but I use /packer/

http://johannburkard.de/blog/programming/javascript/automate-javascript-compression-with-yui-compressor-and-packer.html

It's been really excellent for me.

annakata
+4  A: 

In asp.net AJAX, you can use the 'CompositeScript' tag. This will combile all your scripts into 1 big js file, saving bandwidth by reducing the number of http 304s and possibly http 401s.

Sample:

 <asp:ScriptManager ID="ScriptManager1" runat="server">
        <CompositeScript>
            <Scripts>
                <asp:ScriptReference Path="~/Scripts/Script1.js" />
                <asp:ScriptReference Path="~/Scripts/Script2.js" />
                <asp:ScriptReference Path="~/Scripts/Script3.js" />
            </Scripts>
        </CompositeScript>
    </asp:ScriptManager>

For more info, see here: http://msdn.microsoft.com/en-us/library/cc488552.aspx

desigeek