Skip to content


Setting up a JavaScript Build Process

It’s important to have a build process for complex JavaScript applications. Probably not something you would setup for an average website. JavaScript builds are better suited for web applications & script libraries. As Julien Lecomte said in his article about building web applications with Ant:

Such applications cannot efficiently be developed without relying on a solid build process to do all the dirty and repetitive work of reliably putting all the pieces together.

So its about time you setup your own build process. Julien’s blog post is great but I’m gonna start with the basics and try to give you all the info you need to get up and running asap. Everything fromorganizing the directories right down to the commands to run the build. This will help you get going with something you can build on (no pun intended!).

Over time I’ll post more advanced task I have in my build process but for now we’ll focus on the basics. At the end of this post are some links to extra resources so you can dig into more details about the tools used here.

Directory Structure
Directory Structure

  • My Projects:
    main projects folder for all your applications & libraries
  • sample_project:
    sample project we’ll use to show the build process
  • build:
    the results of a successful build. These files are what get deployed to your server(s).
  • src:
    all your source code for a project
  • shared:
    resources shared between projects
  • bin:
    all the resource files required to get your build going.
  • external:
    external code shared between projects
  • local:
    local code shared between projects

Resources
You will need some well known development tools to get this going… here’s a list with links:
Ant – a build tool used to manage the build process.
Java – the Java Runtime Environment is required for some other tools in build process
YUI Compressor – tool for the compression of both JavaScript and CSS files

Create a folder for YUI compressor in the my_projects/shared/bin directory then unzip and copy over the yuicompressor-x.y.z.jar file from the download.

Ant Build Files
I’m far from an Ant expert but I know enough to get a basic build going so here’s an Ant build.xml for you to experiment with. Open up your favorite text/code editor and drop this xml in there. Save it to your sample_project folder as build.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?xml version="1.0" encoding="ISO-8859-1"?>
 
<!--
   The <project> tag defines the ant project and 
   the default build task to run initiated. It 
   also defines the base directory which is set
   to the current folder this file lives in.
-->
<project name="sample_project" default="build" basedir=".">
   <!--
      The <property> tag defines variables we 
      are using to store the path to different 
      files and tools required and input/output 
      directories. You use those variables by
      like this: ${variable}
   -->
   <property name="BUILD_DIR"      value="build" />
   <property name="SOURCE_DIR"     value="src" />
   <property name="SHARED_DIR"     value="../shared" />
   <property name="EXTERNAL_DIR"   value="${SHARED_DIR}/external" />
   <property name="LOCAL_DIR"      value="${SHARED_DIR}/local" />
   <property name="RESOURCE_DIR"   value="${SHARED_DIR}/bin" />
   <property name="YUI_COMPRESSOR" value="${RESOURCE_DIR}/yui-compressor/yuicompressor-2.4.2.jar" />
   <!--
      The <target> tags defines an ant task.
      You have to give it a unique name and
      list other task (if any) this task 
      depends on. Ant will run those task first.
 
      This task below is the default task defined
      in the <project> tag. It will run all the
      dependents.
   -->
   <target name="build" depends="clean, bundle_javascript, compress_javascript" />
   <!--
      This is the "create JavaScript bundles" task
      used to create concatenated files for each 
      category defined and a main application bundle
      which contains all the code we need in one file.
   -->
   <target name="bundle_javascript">
      <!-- create the output directory for built files -->
      <mkdir dir="${BUILD_DIR}/js"/>
      <echo>Bundle JavaScript Files...</echo>
      <!-- external.js: all shared third party code -->
      <concat destfile="${BUILD_DIR}/js/external.js">
         <fileset dir="${EXTERNAL_DIR}/js" casesensitive="yes">
            <include name="**/*.js"/>
         </fileset>
      </concat>
      <!-- local.js: all shared local code -->
      <concat destfile="${BUILD_DIR}/js/local.js">
         <fileset dir="${LOCAL_DIR}/js" casesensitive="yes">
            <include name="**/*.js"/>
         </fileset>
      </concat>
      <!-- core.js: all the core project related code -->
      <concat destfile="${BUILD_DIR}/js/core.js">
         <fileset dir="${SOURCE_DIR}/js" casesensitive="yes">
            <include name="**/*.js"/>
         </fileset>
      </concat>
      <!-- main.js: the main big bundle of all the previous bundles -->
      <concat destfile="${BUILD_DIR}/js/main.js">
         <filelist dir="${BUILD_DIR}/js/" files="external.js, local.js, core.js"/>
      </concat>
      <echo>JavaScript Bundles Done!!!</echo>
   </target>
   <!--
      This task will compress the main.js bundle using YUI 
      compressor and rename the file main.compress.js
   -->
   <target name="compress_javascript" depends="bundle_javascript">
      <echo>Compressing JavaScript Files...</echo>
      <apply executable="java" parallel="false">
         <fileset dir="${BUILD_DIR}/js" includes="main.js"/>
         <arg line="-jar"/>            
         <arg path="${YUI_COMPRESSOR}"/>            
         <srcfile/>            
         <arg line="-o"/>            
         <mapper type="glob" from="*.js" to="${BUILD_DIR}/js/*.compress.js"/>            
         <targetfile/>
      </apply>
      <echo>JavaScript Compression Done!!!</echo>
   </target>
   <!--
      This task will clean out any previous build files by
      deleting the current build folder and re-creating it
   -->
   <target name="clean">
      <echo>Delete old build folder...</echo>
      <delete dir="build"/>
      <echo>Create new build folder...</echo>
      <mkdir dir="${BUILD_DIR}"/>
   </target>
</project>

Go over the comments to get an idea of what’s going on in this file.

The Process
So what’s the process? It’s all outlined in the Ant build file. A typical JavaScript build usually consist of code concatenation, compression and deployment to a build folder ready to get used by whatever needs to consume it. Each of these task are defined as nodes. One task can trigger others based on dependencies. So in practice, once your done coding your super cool long awaited web app and your ready to test it out… pick a build task and run the build.

Build It!!
To build your app you’ll need to navigate to your project folder from the command line. The same spot where the build.xml file lives. And type “ant” then the enter key. You’ll get some output on the screen as Ant goes through each task. If it fails it you’ll get something like “Build Failed…”. Double check the build file, your folders, files, paths and all that. If the build is successful then you see something like “Build Successful…”.

That’s it…the build folder will have all the output files. I encourage you to play around with Ant and customize the build file to something your comfortable with.

You can learn more about Ant from these books:
Ant: The Definitive Guide
Ant in Action
Pro Apache Ant

Next time I’ll talk about creating different builds for different environments and also deploying your code to your web server.

Send me any questions or feedback you may have to my twitter at http://twitter.com/JavaScriptr or hit me up on our contact form.

Posted in Coding Practices, JavaScript, Resources.

Tagged with , , , , , .