If you are a Force.com developer who has to write Visualforce pages and some bit of JavaScript, you surely would get frustrated with the slow “file-save” timings that you find with Force.com Eclipse IDE. While it is powerful, it also gets slow and irritating - especially when its not even compiling anything for a JavaScript resource.

Eclipse IDE Force.com

Additionally, like me, you may not like writing javascript in Force.com IDE at all - it is not the best JS editor.

If you have quite a few javascript or css files, its better to use compressed resources. But one of the reasons people don’t create a compressed static resource in Force.com is that it’s a bit of a pain to edit its contents.

One way out is to use the Eclipse Zip Editor plugin but it tends to the save-stuff even slower. And if you have a compressed resource for styles & heavy images - it is way too slow to save a single CSS file.

Because of this many developers start writing code JS and CSS in Visualforce pages, and end up mixing JS CSS VF code all in one. For example, it ends up something like below and takes up a lot of time refactoring.

<apex:page >
<style>
    .formCheckbox{
       vertical-align:bottom;
    }
    .tableCellSpace {
        padding-bottom:10px;
    }
</style>
<script>
  function foo() {
	var label = '{!$Label.SomeLabel}'

	/* And some code like
                (Indented with new lines only to fit correctly) */
	document
         .getElementById('{!$Component.someApexForm.someApexElementID}')
           .value = 'something'; 

	/* And sometimes people write horrible hard-to-separate code .
	 -- this I consider as bad abuse of template language... */
	var i=0;
	var arr = new Array();
	<apex:repeat value="{!list}" var="listItem" >
	    arr[i] = new Array(2);
	    arr[i++][0]='{!listItem}';
	</apex:repeat>
  }
</script>
.......
</apex:page >

It is good practice to keep JS and CSS stuff separated right from the beginning to avoid such cases.

One of the productive technique, that works best for me even when working with large javascript code bases with VisualForce, is to use a local server to host the JS file. i.e using http://localhost:NNNN/....

Not trying “file://” since that has too many restrictions and removing those restrictions can particularly make general browsing unsafe.

This local server may be anything - Tomcat, IIS, python-httpserver, etc.. Or a CherryPy server.

<script src="{!$Resource.foo}"  type="text/javascript"></script>
<!-- It will be {!$Resource.foo}/sample.js  - in case of compressed resources -->

Instead of accessing your JS file from Force.com (shown above), you can access it from the local machine as shown below:

<script src="http://localhost:8080/static/sample.js" type="text/javascript"></script>

And you cannot completely do away with script stuff on the Visualforce tab - but can minimize it to accessing server side resources.

<script>
	var labels = {
		MyLabel: {!$Label.Mylabel}
	}
	/* Usage in js file --  labels.MyLabel */
</script>

You can use any editor like Notepad++ or TextMate, save the JS file instantaneously locally and refresh the page.

If you use Google Chrome, you will get the content blocked error.

Chrome - local content blocked

To resolve this, you will need to start Chrome with --allow-running-insecure-content flag. This is required because your page URL would be secure https://... while the local server uses http://. This flag is not required if you are using Firefox (tested on v18). You can simply create a batch file for launching Chrome when developing:

# chrome_insecure.bat
c:\path-to-chrome-exe>>\chrome.exe --allow-running-insecure-content

Now Chrome will display a warning in console and continue

Chrome warning

If you intend to use CherryPy server, the code for the applicaiton hosting these static files is simple

You can download the python code here

# jsLoader.py -- Simple CherryPy server that serves static content
# http://localhost:8080/static/
# Port may change and will be shown in command window
#!/usr/bin/python

import cherrypy
import os

class HelloWorld(object):

	@cherrypy.expose
	def index(self, **params):
		return "Hello World!"
config = {'/static':
                {'tools.staticdir.on': True,
                 'tools.staticdir.dir': os.path.dirname(os.path.abspath(__file__))+'/static',
                }
        }
cherrypy.quickstart(HelloWorld(), '/', config=config)

If you want to use Google App Engine SDK, simply create a new application and add static_dir handlers to app.yaml, shown below. For more information visit Google App Engine - Using Static Files

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: /static
  static_dir: static

- url: .*
  script: main.app
.....

Hope this post was helpful - If you like it please share/like/comment!