Ordering javascript imports

Apr 23, 2013 at 12:08 PM
Hi -

I'm trying to get the compressor set up for my project. We have what can only be described as a buttload of our own and library javascript files which I'd like to concatenate and minify at build time.

The problem I'm having is working out how the order of concatenation is controlled: I need to import my libraries in the correct order so that each file's dependencies are satisfied when its loaded and executed.

Ideally what I'd like is something that looked a bit like:

import file #1
import file #2
...
import all other files in scripts directory in any order.

but if I have to list all the files, that'd be ok.

I've tried
    <JavaScriptFiles Include="($WebProjectOutputDir)/Scripts/file1.js;
($WebProjectOutputDir)/Scripts/file2.js;"/>

      <JavaScriptFiles Include="$(WebProjectOutputDir)\Scripts\*.js" 
      Exclude="@(JavascriptFiles)"/>
    </ItemGroup>
but it doesn't look like my intended ordering is respected.

Is there a way to do what I want to do?
Coordinator
Apr 23, 2013 at 12:24 PM
Hi,

You are falling foul of msbuild - it always orders them alphabetically.
One of the answers here http://stackoverflow.com/questions/7050552/msbuild-item-order-when-using-wildcards links to a custom msbuild task that may help

Other options are:
  • name your files such that the ones you want first appear first in the alphabet
  • Compress each file you want first individually and then lump all the others together - you end up with a few more round trips than you'd like but you still get the benefit of compression.
  • Alter the scripts such that load order isn't important - it seems to me a bit brittle
Sorry there's no one easy answer to this one, but blame MSBuild for it :)
Apr 23, 2013 at 2:22 PM
It's only the wildcard search that is ordered alphabetically, msbuild actually guarantees the order is maintained, see here: http://stackoverflow.com/questions/1219859/do-items-in-msbuild-file-maintain-their-order-when-passed-to-a-task .

The reason my code wasn't working was just because I had the $ and the ( the wrong way round, so file1.js and file2.js were being read in in the directory search, rather than being added at the start.

This version:
 <JavaScriptFiles Include="$(WebProjectOutputDir)/Scripts/file1.js"/>
 <JavaScriptFiles Include="$(WebProjectOutputDir)/Scripts/file2.js"/>

      <JavaScriptFiles Include="$(WebProjectOutputDir)\Scripts\*.js" 
      Exclude="@(JavascriptFiles)"/>
    </ItemGroup>
will do what I wanted.
Coordinator
Apr 23, 2013 at 2:25 PM
Lol, I didn't spot that either :) Glad you're up and running now anyway...