Upgrading from an ancient version of closure, migrating old arguments/behavior

30 views
Skip to first unread message

Emmanuel Schanzer

unread,
Jul 11, 2022, 2:57:14 AM7/11/22
to Closure Compiler Discuss
Hi all - back in 2009, a grad student used the closure compiler for a project called WeScheme, which allowed students to program in the Racket programming language entirely in the browser. This is boring news now, but back in the day it felt like we'd landed on the moon. :-)

The build script at the time used a bizarre collection of bash, racket, any python calls to glue everything together. Now it's 2022, I've inherited the code, and I'm trying to modernize the build script. However, a lot has changed in the last 13 years! I'm totally new to the closure compiler, and I've been trying to consume the Wiki and various stack overflow posts...there's a lot out there to digest!

As far as I can tell, the build script first calculates the dependencies for provides/requires across our codebase. Here's the racket-syntax for calling out to the python:

(call-system "python"
    "war-src/closure/bin/calcdeps.py"
    "--dep" "closure"
    "--path" "js"
    "--output_mode" "deps"
    #:pipe-output-to "deps.js")


This generated a deps.js file with the file paths and arrays for required and provided symbols. I was able to replicate this steps via the newer npm package for the compiler, which appears to call out to the java port of the original python script. This code now generates the right dependency file:

(call-system "node"
   "node_modules/google-closure-deps/bin/closuremakedeps.js"
   "--root" "war-src/js
   "-f" "node_modules/google-closure-library/closure/goog/deps.js"
    "--closure-path" "node_modules/google-closure-library/closure/goog"
   #:pipe-output-to "war-src/deps.js")

Success! On to compilation...

The old script then compiles one file at a time from a directory,  specifying that file as input and setting paths for dependency calculation, and spitting out the compiled result :

(call-system "python"
               (build-path closure-dir "bin" "calcdeps.py")
               "-i" "war-src/js/SOMEFILE.js")
               "-p" (path->string closure-dir)
               "-p" "war-src/js"
               "-o" "script"
               #:pipe-output-to "war/js/SOMEFILE-new.js"))


I've been trying to port this, but the compiler no longer accepts path arguments for dependency calculation and it doesn't seem to use the generated deps.js file from the first step. The input file has dependencies that exist in the closure library, but also in sibling files in the same directory. Here's my best-effort thus far:

(call-system "node"
             "node_modules/google-closure-compiler/cli.js"
             "--js" "war-src/js/SOMEFILE.js"
             "--js" "war-src/js/**/*.js"
             "--js" "node_modules/google-closure-library/**/*.js"
             "--strict_mode_input" "false"
             #:pipe-output-to "war/js/SOMEFILE-new.js"))

This triggers a java error - I think because SOMEFILE is inclided twice and is resolving to the same chunk.  For what it's worth, here's the same command, done by hand in the commandline with a specific file:

node ./node_modules/google-closure-compiler/cli.js \
  --js war-src/js/splash.js \
  --js war-src/**/*.js \
  --js node_modules/google-closure-library/**/*.js \
  > ~/Desktop/splash-new.js

How can I replicate the old behavior? Is there another mechanism altogether that I should be using?

Thanks in advance for any advice, and apologies for any clumsy wording/descriptions. 

Emmanuel

Emmanuel Schanzer

unread,
Jul 11, 2022, 7:23:37 AM7/11/22
to Closure Compiler Discuss
Hi all - it looks like the --entry-point option might be what I want.

Here's the code I'm working with now, which generates a  [JSC_MISSING_ENTRY_ERROR] required entry point "/war-src/js/SOMEFILE" never provided error:

  (call-system "node"
             "node_modules/google-closure-compiler/cli.js"
             "--js" "war-src/js/**/*.js"
             "--js" "node_modules/google-closure-library/**/*.js"
             "--entry_point" "/war-src/js/SOMEFILE.js"
             "--strict_mode_input" "false"
             "--dependency_mode" "PRUNE"
             #:pipe-output-to "war/js/SOMEFILE-new.js)


I've seen a number of threads talking about the complexities of specifying the path for the entry point, and I've tried several variations:
/war-src/js/SOMEFILE.js
./war-src/js/SOMEFILE.js
/war-src/js/SOMEFILE
./war-src/js/SOMEFILE

1) Am I on the right track?
2) Is there a place where the workings of this argument are documented in detail?

Stanimir Mladenov

unread,
Jul 11, 2022, 11:50:24 PM7/11/22
to Closure Compiler Discuss
We have modernized such application constantly and even that semi-regularity, it was hard sometimes.
Maybe you can ditch your build script for something easier, like rules_closure which uses bazel.build.
Another way is to use rules_nodejs, which is again bazel build, but closure to the manual way you have used in your build scripts.

Starting the build is probably the easiest part. After that you will have to replace deprecated and removed features, thousands of errors and warnings.
About the errors and code modifications, using neovim with tree-sitter helped us a lot.

Emmanuel Schanzer

unread,
Jul 12, 2022, 7:57:16 AM7/12/22
to Closure Compiler Discuss
Thanks - I think you're absolutely right, and in the long run I'd definitely like to see the script replaced with something more modern! Migrating the compilation to something modern is just the first step.

I found some good discussion of how --entry_point gets resolved, and I'm happy to report that things are building again! Looking forward to learning how I can integrate this into a modern build system like the ones you describe. :-)
Reply all
Reply to author
Forward
0 new messages