-
Notifications
You must be signed in to change notification settings - Fork 1
musictheory.net Changes
- Added
ast_maul
, which implements global name mangling (see description below). Use the--maul
command line options to turn on mauling. - Pulled https://github.com/mishoo/UglifyJS/pull/316 from laverdet
- Incremented stack size in uglifyjs to 8MB, due to errors when build the ignore file. (Can also use
--no-seqs
, See mishoo/UglifyJS/issues/362.) - Added
--input-state-file
and--output-state-file
, used to persist theoptions.state
object between invocations of uglifyjs. While onlyast_maul
usesoptions.state
at the moment, it may be useful for additional transformations in the future. - Added
--reserved-names-from-file
, similar to--reserved-names
, but the name list is read from a file rather than stdin.
musictheory.net has three main JS modules: a library of core functions (similar to Prototype.js or underscore.js), a library for UI widgets, and a library for shared exercise code. Consolidation into one JS file is not possible due to bandwidth concerns.
Exercises on the site require all three libraries. Lessons and tools need only the Core and UI modules. The rest of the site just needs Core.
In visual form, the dependency tree looks like this:
Google's Closure Compiler requires that manual exports and imports be set up between each module. This was not acceptable for our needs.
Enter the Mauler addition to UglifyJS. When --maul
is specified as a command-line option to uglifyjs
, ast_maul
is ran on the AST prior to ast_mangle
. Maul works as follows:
- Names are transformed to a (hopefully shorter) mauled name form consisting of
$
followed by[A-Za-z0-9]+
. This affects function names, variable names, dot-syntax references, and object literal keys. - The mapping of name to mauled name is global and persistent. Once the name
Foo
is mapped to the mauled$Aa
, all references ofFoo
, regardless of scope, become$Aa
.$Aa
will never be reused for another name. - Mappings may be shared among modules using
--input-state-file
and--output-state-file
. - Like Closure, string literals are never changed. Refer to Inconsistent Property Names for more information. Use the
--maul-print-conflicts
command-line option to show detected inconsistent property names. - Like
ast_mangle
,ast_maul
ignores all reserved names (--reserved-names
).
For my reserved names list, I use the contents of the externs directory from Closure Compiler.
svn checkout http://closure-compiler.googlecode.com/svn/trunk/externs
cat externs/* >> externs.js
uglifyjs --no-seqs --maul-make-reserved-names externs.js >> reserved_names
# Build core.js first
#
uglifyjs --maul --reserved-names-from-file reserved_names \
--output-state-file core.state \
--overwrite core.js
# Now process ui.js, which depends on core.js
#
uglifyjs --maul --reserved-names-from-file reserved_names \
--input-state-file core.state \
--output-state-file ui.state \
--overwrite ui.js
# Now process exercises.js, which depends on ui.js + core.js.
# ui.sym contains the symbols for both core.js and ui.js
#
uglifyjs --maul --reserved-names-from-file reserved_names \
--input-state-file ui.state \
--output-state-file exercises.state \
--overwrite exercises.js
# Process a_site_page.js, which depends on just core.js. Hence, we
# only need the mauled names from core.state. Nothing depends on
# a_site_page.js, so we don't need to specify an output symbol file
#
uglifyjs --maul --reserved-names-from-file reserved_names \
--input-state-file core.state \
--overwrite a_site_page.js
# Process an_exercise_page.js, which depends on core.js, ui.js, and
# exercises.js. exercises.state contains the mauled names for all
# three files.
#
# As before, nothing depends on an_exercise_page.js, so we don't need to
# specify an output symbol file
#
uglifyjs --maul --maul-ignore-list ignore \
--input-state-file exercises.state \
--overwrite an_exercise_page.js