CSS and JavaScript build process

I've experimented with various development and build processes for CSS and JavaScript files. I want an flexible system for development and an efficient system for production. This article outlines what I am currently using in the code I'm developing to run my blog on server-side JavaScript.

Development

The development file structure is optimized for flexibility and avoiding working on 3000 line files by splitting development code into dependency files in a src/ directory and linking these files together in a build/ directory.

The public/ directory is the root directory for absolute urls.

file structure

  • public/
    • content.html
    • build/
      • css/
        • presentation-CACHEVERSION.css
      • js/
        • behavior-CACHEVERSION.js
    • src/
      • css/
        • one.css
        • two.css
      • js/
        • alpha.js
        • beta.js

public/content.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>

  <title>Content Page</title>

  <link href="/build/css/presentation-CACHEVERSION.css" rel="stylesheet" type="text/css">
  <script src="/build/js/behavior-CACHEVERSION.js" type="text/javascript"></script>

</head>
<body>

  <h1>Interesting Content</h1>
  
  <p>Lorem ipsum</p>

</body>
</html>

public/build/css/presentation-CACHEVERSION.css

@import url(/src/css/one.css);
@import url(/src/css/two.css);

public/build/js/behavior-CACHEVERSION.js

document.write('<script src="/src/js/alpha.js" type="text/javascript"><\/script>');
document.write('<script src="/src/js/beta.js" type="text/javascript"><\/script>');

public/src/css/one.css

/* docs */
h1 {
  color:#FF0000;
}

public/src/css/two.css

/* docs */
p {
  color:#0000FF;
}

public/src/js/alpha.js

// docs
alert('alpha.js');

public/src/js/beta.js

// docs
alert('beta.js');

Production

The automated build process prepares the site for production.

Each file in public/build/ is parsed to determine its dependency development files. The date of the most recently modifed of these files is noted. These files are concatenated, and minified. The production file is created with the -CACHEVERSION replaced with the date of the most recently modified dependency file.

All references to -CACHEVERSION in the application are replaced with the appropriate timestamp for each build file.

The production web server is set to serve the files in the public/build/ directory with the header Cache-Control: max-age=31536000. If the client has the file in its cache then it should not check for a more recent version on the server for one year. If we do modify the code in the development css and js files then the timestamp on the build file will change and the client will ask for the new version from the server.

The public/src/ directory is deleted.

file structure

  • public/
    • content.html
    • build/
      • css/
        • presentation-20080125135221.css
      • js/
        • behavior-20071208124237.js

public/content.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>

  <title>Content Page</title>

  <link href="/build/css/presentation-20080125135221.css" rel="stylesheet" type="text/css">
  <script src="/build/js/behavior-20071208124237.js" type="text/javascript"></script>

</head>
<body>

  <h1>Interesting Content</h1>
  
  <p>Lorem ipsum</p>

</body>
</html>

public/build/css/presentation-20080125135221.css

h1{color:#FF0000;}p{color:#0000FF;}

public/build/js/behavior-20071208124237.js

alert('alpha.js');alert('beta.js');

Variations

As a simpler alternative, instead of using timestamps for each production file, the same release version number could be use on all files.

As an even simpler alternative, don't use -CACHEVERSION at all have the client check for a newer version with the server each time a page includes that build file. This still takes advantage of concatenation and minification and makes for a simpler build process then all the timestamping business.

Comments

Have something to write? Comment on this article.