closure-pro-build
v0.1.0
Published
Build projects using some or all of Closure's JS Compiler, Templates (Soy), Stylesheets (GSS), and JS Library.
Downloads
5
Readme
closure-pro-build
Closure Project Builder: An npm, node.js package that makes it super easy to build projects using some or all of Closure's JS Compiler, Templates (Soy), Stylesheets (GSS), and JS Library.
Check out closure-bxr-starter for a sample starter project using closure-pro-build (along with Bootstrap, Express, jQuery, and RECESS).
Features
- Can have multiple JS/Soy modules (multiple output JS files that can be loaded when needed on clients, servers, or both).
- Automatically calculates Closure dependencies & moves input files common to multiple modules into parent modules to prevent duplicate code loading.
- Input JS files can be:
- Fully Closure-compatible (using
goog.require()
,goog.provide()
). - Partly Closure-compatible (not using
goog.require()
,goog.provide()
), still run through compilation & minification. - Directly included without compilation or minification.
- Fully Closure-compatible (using
- Input CSS files can be:
- GSS files (supports mixins, functions, basic logic) compiled by Closure Stylesheets (GSS) compiler.
- Regular CSS files compiled by Closure Stylesheets (GSS) compiler.
- Directly included without compilation or class renaming.
- Supports debug (human readable) & release (fully minified) compilation modes.
Usage
Sample usage for a project using a CSS module (for application and 3rd party CSS) and 2 JS modules (one for server-side Soy templates to render initial HTML page and the other for all client-side JS that will be downloaded by users):
var closureProBuild = require('closure-pro-build');
var projectOptions = {
rootSrcDir: 'src/',
cssModule: {
name: 'style',
description: 'All CSS styles for the project',
closureInputFiles: ['main.gss', 'other.css'],
dontCompileInputFiles: ['path/to/some/third_party.css']
},
jsModules: {
page: {
description: 'Soy template for shell HTML, loads main JS and CSS',
closureRootNamespaces: ['sample.page']
},
main: {
description: 'Main JS module, with all client-side JS',
closureRootNamespaces: ['sample.main'],
nonClosureNamespacedInputFiles: ['path/to/some/non-closure-lib.js'],
dontCompileInputFiles: ['path/to/wont-minify-this.js']
}
}
};
var buildOptions = {type: closureProBuild.RELEASE};
closureProBuild.build(projectOptions, buildOptions, function(err) {
if (err) {
// ...Handle the Error...
return;
}
// Success: style.css, page.js, main.js were output to build/release/.
});
Input Files
All InputFiles
parameters are handled as follows:
- Paths are interpreted relative to the
rootSrcDir
specified in the project options (defaults to current working directory,.
). - Single File: include full paths using forward slashes, e.g.
['path/to/my/file.js']
. - Glob Regex Pattern: use minimatch style patterns with
*
,**
, and other regex characters to match many files that fit the given pattern. Some common examples:['style/*.css']
: matches all .css files in thestyle/
directory.['style/**/*.gss']
: matches all .gss files recursively under thestyle/
directory.['**/*_layout.css']
: matches all files recursively that end in_layout.css
.
- If a path contains backslashes (but no forward slashes or glob regex special characters), then the backslashes are converted to forward slashes and treated as single files.
System Requirements
Java 7+ and Python 2 must be installed and part of the system path as java
and python
in order to run all Closure tools. These commands are also configurable via buildOptions
(e.g. in case python
would resolve to Python 3 on your system).
Project Options
Each CSS or JS module specifies the input files that should be compiled (or not) and combined together to produce a single output CSS or JS file for that module. In the case of JS files using goog.require()
and goog.provide()
, these input files are specified by listing the root namespace(s) that transitively goog.require()
all the JS that should be included in that module.
Required
- cssModule: JS Object map with these properties:
- name: (Optional) Name for CSS module (controls output file name). Defaults to
'style'
. - description: String that describes the module (for documentation).
- closureInputFiles: (If any) List of GSS or CSS files that should be compiled & minified (including CSS class renaming) using the Closure Stylesheets compiler. Any CSS classes from these files should be accessed via
goog.getCssName('theClassName')
in JS or{css theClassName}
in Soy. - dontCompileInputFiles: (If any) List of CSS files that should not be compiled by the GSS compiler (so no minification or CSS class renaming). CSS classes from these files should be accessed normally in JS or Soy (NOT using
goog.getCssName()
or{css}
). This CSS will be included in the output before any closureInputFiles.
- name: (Optional) Name for CSS module (controls output file name). Defaults to
- jsModules: JS Object map from module name (determines output JS filename) to an object with these properties:
- description: String that describes the module (for documentation).
- alwaysLoadedAfterModules: (If any) List of JS module names that this module depends on (that will always be loaded before this one). Only immediate deps need to be specified; will automatically consider transitive dependencies.
- closureRootNamespaces: (If any) List of the root Closure namespace(s) that transitively
goog.require()
all the Closure-namespaced JS that should be included in this module. This code can rely on allnonClosureNamespacedInputFiles
anddontCompileInputFiles
from this module (and parent modules) having been loaded first. - nonClosureNamespacedInputFiles: (If any) List of the JS files that do NOT use
goog.require()
orgoog.provide()
but that should still be compiled (including symbol renaming) by the Closure JS Compiler. These files must be specified in dependency order (such that a file only depends on files listed before it being loaded). These files will be loaded after anydontCompileInputFiles
. - dontCompileInputFiles: (If any) List of JS files that should NOT be compiled or minified by the Closure JS compiler. These files must be specified in dependency order (such that a file only depends on files listed before it being loaded). These files will be loaded before any
nonClosureNamespacedInputFiles
.
Optional
- rootSrcDir: Path to root source directory, which all
InputFiles
paths will be interpreted as relative to. Defaults to current working directory (.
). For example,'src/'
is a very common root source directory for many projects. - closureRootDirs: For fully Closure-compatible JS, list of root directories for Closure to recursively search under to resolve
goog.require()
dependencies. Directory paths are interpreted relative torootSrcDir
. Defaults to['.']
(i.e. searches everywhere underrootSrcDir
). Closure JS Library directories are automatically searched, so don't list them. - soyInputFiles: List of input Soy files to compile to JS files using the Closure Templates compiler. Defaults to
['**/*.soy']
, which will automatically find any .soy files recursively underrootSrcDir
and won't invoke the Closure Templates compiler at all if there are no matching .soy files. This option only needs to be set to choose particular input files or to include .soy files from outside directories. See the Using Soy in JS Modules section below for more information. - jsExterns: A list of externs files (relative to the current directory) to tell the Closure Compiler not to rename externally defined symbols (e.g. when loading jQuery via CDN script tag).
- jsWarningsWhitelistFile: A whitelist file (relative to the current directory) for JS compiler warnings where each line is of the form:
path/to/file.js:{line-number} {first-line-of-warning}
- For example: src/main.js:294 Suspicious code. This code lacks side-effects. Is there a bug?
Build Options
Required
- type: The type of build, either
closureProBuild.RELEASE
(fully minified) orclosureProBuild.DEBUG
(human readable).
Optional
- generatedCodeDir: What directory should generated code be put under (relative to current working directory)? default: gen/
- tempFileDir: What directory should temporary build files be put under (relative to current working directory)? default: tmp/
- outputDir: What directory should output JS and CSS files be placed under (relative to current working directory)? default: build/
- python2Command: What command is used to invoke Python version 2? default: python
- javaCommand: What command is used to invoke Java? default: java
- suppressOutput: True to suppress any standard output/error stream output during compilation. default: false
Using Soy in JS Modules
First, make sure all your Soy templates are being compiled:
- If all your .soy files are under
rootSrcDir
(or subdirectories), then this happens automatically. - Otherwise, manually set
soyInputFiles
to match all of your .soy templates.
Let's assume the Soy template you want to use starts out like this:
{namespace mysite.soy autoescape="contextual"}
Then all you need to do is add goog.require('mysite.soy');
to the top of the JS file you want to invoke the Soy template from. (Of course, make sure that JS file is transitively goog.require()
'd from your JS module's closureRootNamespaces
).
General Notes
- In all compiled JS, you typically want to access properties as
foo.bar
(NOTfoo['bar']
), since these symbols will be obfuscated in the compiled output (so the quoted string lookup would fail). - The only possible exception to this is when interacting with JS that is compiled separately (or listed in
dontCompileInputFiles
) from your compiled JS, where you should do one of two things:- Always use quoted strings to access these properties (e.g.
window['foo']['bar']
). - Use an externs file via
jsExterns
project option to tell the Closure JS Compiler that certain symbols will be provided externally (so they shouldn't ever be renamed). In that casefoo.bar
access is fine, since the compiler will know not to rename those symbols.
- Always use quoted strings to access these properties (e.g.
See also the externs files provided for convenience (such as for jQuery) in closureProBuild.EXTERNS
, defined in closure-pro-build.js. If more externs files would be generally useful, feel free to contribute them.
Planned Features
Future support is planned for:
- Message translation tools & separate output files for each supported locale.
- RTL flipping of CSS styles (e.g.
"left: 20px"
becomes"right: 20px"
) for RTL locales.
License & Copyright
This package is released under the Apache License, Version 2.0. See LICENSE file for details.
License information for 3rd party tools used can be found under the 3p/
folder. License information for other npm packages used can be found in the information and/or source code for those packages listed on the npm website.
Copyright © 2013 Eric W. Barndollar.