Drop-in patches for Sencha Cmd’s JavaScript compiler and newest Google Closure Compiler integration.
Fixes invalid or fragile JavaScript emitted from Sencha’s AST pipeline so modern syntax survives minification and mangling.
Applying the patch · Build from source · What changes · Releases
Sencha Cmd ships a bundled compiler (sencha.jar) and a pinned Closure Compiler. This repository rebuilds selected classes against your Cmd version, bundles a newer Closure Compiler, and packages everything as a small overlay you can drop onto an existing no-jre Cmd install.
CI builds one archive per supported Cmd version; pick the zip that matches the Cmd you run in production.
| Requirement | Notes |
|---|---|
| Sencha Cmd (no-jre) | Use the distribution without a bundled JRE. You provide the JVM. Supported Cmd versions: 7.9.0, 8.0.0 (see release workflow). |
| Java 21+ | Required to run patched Cmd and to build the patch locally (matches CI). |
| curl and tar | Needed by download.sh when building from source. |
| Gradle | Wrapper not required; use a local Gradle install or the Gradle that ships with your IDE. |
Set JAVA_HOME to a JDK 21 installation before running sencha or gradle.
Pre-built artifacts are published on GitHub Releases when a version tag (v*) is pushed. The Release workflow builds patch-cmd-<sencha_version>.zip for each matrix entry (currently 7.9.0 and 8.0.0).
- Open Releases.
- Choose the tag you need (for example
v1.0.0). - Download
patch-cmd-<your-cmd-version>.zip— the Sencha Cmd version must match exactly (e.g.patch-cmd-7.9.0.zipfor Cmd 7.9.0).
Extract the zip and copy files into the root of your Sencha Cmd installation (the directory that already contains sencha.jar, lib/, b/, etc.):
| From archive | Into Cmd install |
|---|---|
sencha.jar |
Replace sencha.jar at the Cmd root |
lib/closure-compiler-*.jar |
lib/ |
lib/closure-compiler-externs-*.jar |
lib/ |
The patched sencha.jar manifest Class-Path expects the compiler under lib/ and externs under b/, with the filenames shipped in the archive. Remove older closure-compiler-* JARs in those folders if names changed, so only the versions referenced by the new manifest remain.
Back up the original sencha.jar and Closure JARs before overwriting.
Point your environment at JDK 21 and run Cmd as usual, for example:
export JAVA_HOME=/path/to/jdk-21
sencha app buildUse this when hacking on the sources or targeting a Cmd version that already has a matrix row in CI.
download.sh fetches the platform-specific npm package (@sencha/cmd-macos or @sencha/cmd-linux-64) and extracts sencha.jar into input/sencha.jar (compile-only baseline for Gradle).
./download.sh 7.9.0 # or 8.0.0Supported platforms: macOS and Linux x64 (same platforms as the npm packages). Requires curl and tar.
With input/sencha.jar in place:
gradle createPatchThis task:
- Compiles patched sources from
src/againstinput/sencha.jarand Closure (compile-only). - Writes output to
patch/:patch/sencha.jar— original Cmd jar plus replaced classes and an updated manifest (Closure paths updated).patch/lib/— resolved Closure Compiler and externs JARs.
To produce the same zip CI uploads:
(cd patch && zip -r ../patch-cmd-7.9.0.zip .)Use the Cmd version you passed to download.sh in the archive name.
./download.sh 8.0.0
gradle createPatchThe stock AST → JavaScript path had several cases that produced invalid or mangling-unfriendly output. This patch addresses them in-tree.
Parentheses were omitted for any single-parameter arrow function. That is only valid for a simple binding (x => …). Destructuring, rest, and default-destructuring parameters must be wrapped.
Now parenthesized when the lone parameter is:
- Object destructuring —
({ a, b }) => … - Array destructuring —
([a, b]) => … - Rest —
(...args) => … - Default with destructuring binding —
({ a } = defaultObj) => …
DefaultParameter inside object patterns was folded like a literal property, dropping the binding. ObjectPattern overrides addProperty() so destructuring defaults print correctly.
Shorthand was emitted as { foo }. Some pipelines mishandle it. SourceBuilder.onObjectProperty always emits explicit name: value pairs.
ClosureCompressor.java is updated to align Sencha’s Closure integration (options, polyfills, transpile-only paths, error filtering) with the newer compiler bundled in the patch.