Note: The calcdeps.py
script is deprecated, and so is this document. See Using ClosureBuilder for information on closurebuilder.py
, the new recommended dependency resolution script.
Getting Started with the Closure Library illustrates an easy way to use the Closure Library in your web pages. This article illustrates a different way to include Closure JavaScript: by building one big JavaScript file containing everything you need from the Closure Library. The approach illustrated here involves an extra step, but produces better performance for large projects.
Why calcdeps.py?
If you did the Hello World exercise
in Getting Started with the Closure
Library, you may have noticed that the browser made several HTTP
requests during page load. For each necessary Closure Library file,
the goog.require()
function creates a new script tag to
load the file. Each Closure Library file loaded thus produces a new
HTTP request.
If you use the Closure Library for a large web application, your application may load faster if you assemble all required Closure Library files together with your own JavaScript into one big file, so that there are fewer round trips to the server and back to the browser.
The calcdeps.py
script located
in closure-library/closure/bin
makes this possible. It
calculates the set of Closure Library files your JavaScript program
needs (the dependencies of your JavaScript, in other
words). It can then combine those files into a single file.
During development and debugging, you may wish to continue using the
approach illustrated in the Hello World, since it allows you to
quickly make a change in your script and reload the page in the
browser to see the effect, without having the extra step of
running calcdeps.py
. But it's a good idea to
use calcdeps.py
for your finished product.
Resolving Closure Library Dependencies with calcdeps.py
This example takes the JavaScript from
the Hello World example and
uses calcdeps.py
to generate a single script file
containing everything the script needs.
If you haven't already done so, follow the instructions
in Getting Started with the
Closure Library to download and unpack the Closure Library. Create a
JavaScript file named hello.js
containing the following
script, and save it in the same directory that contains
the closure-library
directory.
goog.require('goog.dom'); goog.require('goog.dom.TagName'); function sayHi() { var newdiv = goog.dom.createDom(goog.dom.TagName.H1, {'style': 'background-color:#EEE'}, 'Hello world!'); goog.dom.appendChild(document.body, newdiv); }
This JavaScript is identical to the code used in Getting Started with the Closure Library.
Execute the following command from the directory
containing hello.js
:
closure-library/closure/bin/calcdeps.py -i hello.js \ -p closure-library/ -o script > hello-calc.js
Now open hello-calc.js
. You should see many lines of new
code. If you look at the very bottom of the file you should see the
original sayHi()
function. The calcdeps.py
script has concatenated all of the Closure Library packages needed by
the original JavaScript, together with the original script itself.
The calcdeps.py
script reads
the goog.require()
statement in the hello.js
input file and figures out what parts of the Closure Library are
needed to fulfill that
requirement. See Finding Your Way
around the Closure Library for more information
about using goog.require()
statements.
The above command specifies three options:
-i hello.js
- The input file that needs packages from the Closure Library.
-p closure-library/
- The path to the Closure Library.
-o script
- The type of output to print. In this case we want to print the text of the concatenated JavaScript.
See calcdeps.py Options below for a complete list of the script's options.
To see the output JavaScript in action, create an HTML file with a
script tag for hello-calc.js
, and add
an onload
handler to the body tag to call
the sayHi()
function.
<html> <head> <script src="hello-calc.js"></script> </head> <body onload="sayHi()"> </body> </html>
When you load this page in a browser, you should see the message "Hello world!"
Shrinking Code with calcdeps.py and the Closure Compiler
The calcdeps.py
script can also help make your code smaller. With the -o compiled
output option, you can perform the
same dependency resolution step that -o script
performs and then compress the resulting file with the Closure
Compiler.
The following example demonstrates the process of using the Closure Compiler
with calcdeps.py
. For more information about the
compiler and how it compresses JavaScript, see
the Closure Compiler documentation.
To use the -o compiled
output mode, you need the
Closure Compiler executable jar
file. Download
the jar from the repository and put it in the same directory
that contains your closure-library
directory.
Run calcdeps.py
on hello.js
using the following command, which compresses the output with the Closure Compiler:
closure-library/closure/bin/calcdeps.py -i hello.js \ -p closure-library -o compiled \ -c compiler.jar > hello-compiled.js
This command uses same -i
and -p
options
as the example in Resolving Closure Library
Dependencies, but, instead of -o script
, it
uses -o compiled
. It also adds the following new
option:
-c compiler.jar
- The path to the Closure Compiler executable jar.
When you run calcdeps.py
with the -o
compiled
output option, you can also pass options
on to the Closure Compiler. For example, the compiler takes
a compilation_level
option. To set
the compilation_level
to the highest level of
compression, run calcdeps.py
with the following
command:
closure-library/closure/bin/calcdeps.py -i hello.js \ -p closure-library -o compiled \ -c compiler.jar \ -f "--compilation_level=ADVANCED_OPTIMIZATIONS" \ > hello-compiled.js
The calcdeps.py
script passes the
string that follows the -f
option on to the compiler.
See Advanced
Compilation and Externs in the Closure Compiler documentation
for more information about
using ADVANCED_OPTIMIZATIONS
.
calcdeps.py Option Reference
-i INPUTS
or--input=INPUTS
-
The input file or files for which you want to assemble
dependencies. All files that you list as
--input
arguments must be JavaScript files that begin withgoog.require()
statements specifying the dependencies they need fulfilled. -p PATHS
or--path=PATHS
- The paths that should be traversed when looking for required dependencies. In the simplest case, this will simply be the path to the Closure Library. It is possible, however, to add additional libraries to the dependency tree, in which case you may need specify new library paths.
-o OUTPUT_MODE
or--output_mode=OUTPUT_MODE
-
Specifies the type of output
calcdeps.py
generates. The value of this option must be one of the following:list
- Outputs a list of the filenames of all of the JavaScript files that are required by the input scripts.
script
- Outputs the concatenation of all the JavaScript files that are required by the input scripts, together with the input scripts themselves.
deps
-
Outputs a JavaScript file called
deps.js
that specifies a dependency tree for all of the paths listed in the--paths
option. Adeps.js
file allows you to load your own JavaScript files usinggoog.require()
andbase.js
in the same way that the example in Getting Started loads Closure Library files. compiled
-
Performs the same concatenation as
script
, but then passes the result through the Closure Compiler to compress the file. If you use-o compiled
you must include the option--compiler_jar=COMPILER_JAR
(or-c COMPILER_JAR
), where COMPILER_JAR is the path to the compiler executable jar. You may also include the option--compiler_flags="COMPILER_FLAGS"
(or-f "COMPILER_FLAGS"
), where COMPILER_FLAGS is a string containing options to pass on to the compiler.
-
-c PATH_TO_COMPILER_JAR
or--compiler_jar=PATH_TO_COMPILER_JAR
- Specifies the path to the executable Closure Compiler jar.
-
-f "COMPILER_FLAGS"
or--compiler_flags="COMPILER_FLAGS"
- Specifies flags to pass on to the Closure Compiler.