javascript - Prevent RequireJS from Caching Required Scripts

ID : 10226

viewed : 32

Tags : javascriptjqueryrequirejsjavascript

Top 5 Answer for javascript - Prevent RequireJS from Caching Required Scripts

vote vote


RequireJS can be configured to append a value to each of the script urls for cache busting.

From the RequireJS documentation (

urlArgs: Extra query string arguments appended to URLs that RequireJS uses to fetch resources. Most useful to cache bust when the browser or server is not configured correctly.

Example, appending "v2" to all scripts:

require.config({     urlArgs: "bust=v2" }); 

For development purposes, you can force RequireJS to bypass the cache by appending a timestamp:

require.config({     urlArgs: "bust=" + (new Date()).getTime() }); 
vote vote


Do not use urlArgs for this!

Require script loads respect http caching headers. (Scripts are loaded with a dynamically inserted <script>, which means the request looks just like any old asset getting loaded.)

Serve your javascript assets with the proper HTTP headers to disable caching during development.

Using require's urlArgs means any breakpoints you set will not be preserved across refreshes; you end up needing to put debugger statements everywhere in your code. Bad. I use urlArgs for cache-busting assets during production upgrades with the git sha; then I can set my assets to be cached forever and be guaranteed to never have stale assets.

In development, I mock all ajax requests with a complex mockjax configuration, then I can serve my app in javascript-only mode with a 10 line python http server with all caching turned off. This has scaled up for me to a quite large "enterprisey" application with hundreds of restful webservice endpoints. We even have a contracted designer who can work with our real production codebase without giving him access to our backend code.

vote vote


The urlArgs solution has problems. Unfortunately you cannot control all proxy servers that might be between you and your user's web browser. Some of these proxy servers can be unfortunately configured to ignore URL parameters when caching files. If this happens, the wrong version of your JS file will be delivered to your user.

I finally gave up and implemented my own fix directly into require.js. If you are willing to modify your version of the requirejs library, this solution might work for you.

You can see the patch here:

Once added, you can do something like this in your require config:

var require = {     baseUrl: "/scripts/",     cacheSuffix: ".buildNumber" } 

Use your build system or server environment to replace buildNumber with a revision id / software version / favorite color.

Using require like this:

require(["myModule"], function() {     // no-op; }); 

Will cause require to request this file: 

On our server environment, we use url rewrite rules to strip out the buildNumber, and serve the correct JS file. This way we don't actually have to worry about renaming all of our JS files.

The patch will ignore any script that specifies a protocol, and it will not affect any non-JS files.

This works well for my environment, but I realize some users would prefer a prefix rather than a suffix, it should be easy to modify my commit to suit your needs.


In the pull request discussion, the requirejs author suggest this might work as a solution to prefix the revision number:

var require = {     baseUrl: "/scripts/buildNumber." }; 

I have not tried this, but the implication is that this would request the following URL: 

Which might work very well for many people who can use a prefix.

Here are some possible duplicate questions:

RequireJS and proxy caching

require.js - How can I set a version on required modules as part of the URL?

vote vote


Inspired by Expire cache on require.js data-main we updated our deploy script with the following ant task:

<target name="deployWebsite">     <untar src="${temp.dir}/website.tar.gz" dest="${website.dir}" compression="gzip" />            <!-- fetch latest buildNumber from build agent -->     <replace file="${website.dir}/js/main.js" token="@Revision@" value="${buildNumber}" /> </target> 

Where the beginning of main.js looks like:

require.config({     baseUrl: '/js',     urlArgs: 'bust=@Revision@',     ... }); 
vote vote


In production

urlArgs can cause problems!

The principal author of requirejs prefers not to use urlArgs:

For deployed assets, I prefer to put the version or hash for the whole build as a build directory, then just modify the baseUrl config used for the project to use that versioned directory as the baseUrl. Then no other files change, and it helps avoid some proxy issues where they may not cache an URL with a query string on it.

[Styling mine.]

I follow this advice.

In development

I prefer to use a server that intelligently caches files that may change frequently: a server that emits Last-Modified and responds to If-Modified-Since with 304 when appropriate. Even a server based on Node's express set to serve static files does this right out the box. It does not require doing anything to my browser, and does not mess up breakpoints.

Top 3 video Explaining javascript - Prevent RequireJS from Caching Required Scripts