Using the --module option in Closure Compiler to create multiple output files - google-closure-compiler

I'm creating a fairly large library of JavaScript, using Closure Compiler for both its wonderful compression as well as the type-checking and warning systems.
I want to create multiple output files though, because the files are loaded asynchronously (and some files are only loaded on-demand).
Poking around the source code, I've found the --module flag, as well as some related flags. The source code says the following about the option:
A javascript module specification. The format is <name>:<num-js-files>[:[<dep>,...][:]]]. Module names must be unique. Each dep is the name of a module that this module depends on. Modules must be listed in dependency order, and js source files must be listed in the corresponding order. Where --module flags occur in relation to --js flags is unimportant
... and that's all I can find. I'd love to learn more about how to use this option, does anyone have any experience here? Alternatively, if there's another way to create multiple output files, I'm all ears.

java -jar compiler.jar ^
--chunk jq:1: --js jquery-1.6.2.js ^
--chunk t:1:jq: --js test.js ^
--compilation_level ADVANCED_OPTIMIZATIONS
This example will compile out 2 files for you:
jq.js
t.js
jq.js will be jquery 1.6.2 with advanced minification, and t.js will use that minified version of JQuery properly.
I wish there was a JavaFiddle I could post this to to demonstrate it.
Older version
This original answer was for an older version of Closure Compiler. I've left it intact below in case you're in an environment that needs to keep the older version in place.
How to handle multiple output files, aka modules:
http://groups.google.com/group/closure-compiler-discuss/browse_thread/thread/ec7f6809b19b019e/25a94f3994173840
Copy/pasting:
java -jar Build\Tools\compiler.jar ^
--compilation_level=ADVANCED_OPTIMIZATIONS ^
--externs Build\jQuery.externs.js ^
--js Build\Output\Compiling.js ^
--js Script/Themes.lang.js ^
--js Script/Themes.js ^
--module Core:3 ^
--js UI/ThemeChooser/ThemeChooser_en.htm.js ^
--js UI/ThemeChooser/ThemeChooser.js ^
--module UI_ThemeChooser:2:Core ^
--js UI/VerticalTabs/VerticalTabs_en.htm.js ^
--js UI/VerticalTabs/VerticalTabs.js ^
--module UI_VerticalTabs:2:Core ^
--js Pager/Pager_en.htm.js ^
--js Pager/jquery.Pager.js ^
--js Pager/Pager.js ^
--module Pager:3:VerticalTabs ^
--module_output_path_prefix .\Compiled\
And as he notes, --js_output_file is irrelevant when outputting modules.
Note: Apparently the Closure Compiler has changed the arg "--module" to "--chunk". An editor suggested the change; for the newer version I kept the change, for the older version I kept the older argument name, since there are always people out there using older versions of build tools, and that kind of small breaking change can really screw ya up.

Related

Can gprbuild be configured to output gnatprep preprocessed sources?

I have a gpr project which uses gnatprep to preprocess source files. But now I have a tool which needs the already preprocessed source files. I know that I can hunt down each source file and run it through gnatprep:
find . -type f -iname '*.ad[sb]' -exec gnatprep -DSymbol=value {} {}.prep \;
But I'd like to leverage the project file to find the right source files and pass them through. My project file also defines the various symbol values to use, which I would have to add to the command above. Is it possible through some parameter in the .gpr file? E.g.
for Object_Dir use 'obj';
for Preprocessed_Sources_Dir use 'wow_that_was_easy';
You can tell the compiler to leave the preprocessed sources in the Object_Dir with the -gnateG option, like so, in the project file:
package Compiler is
for Default_Switches ("Ada") use ("-gnateDFoo=""Bar""", "-gnateG" );
end Compiler;
The preprocessed source will then be named <original_filename>.prep, for example foo.adb -> foo.adb.prep
Edit:
For your followup-question, you'd have to put the preprocessor options in a separate file, for example prep.def:
* -u -c -DFoo="Bar"
or, if you want to specify options per file:
"foo.adb" -u -c -DFoo="Bar"
And then tell the compiler to use that file with the gnatep= option:
package Compiler is
for Default_Switches ("Ada") use ("-gnateG", "-gnatep=" & Foo'Project_Dir & "prep.def" );
end Compiler;

Executing an executable must be done using a path. Why?

In the following:
Roberts-MacBook-Pro:Code robertnash$ mkdir Flag
Roberts-MacBook-Pro:Code robertnash$ cd Flag/
Roberts-MacBook-Pro:Flag robertnash$ swift package init --type executable
Roberts-MacBook-Pro:Flag robertnash$ swift build
Compile Swift Module 'Flag' (1 sources)
Linking ./.build/debug/Flag
In order to execute the executable, it must be a path, like so
Roberts-MacBook-Pro:Flag robertnash$ .build/debug/Flag
Hello, world!
If I go to where 'Flag' is located, the command cannot be run by simply typing 'Flag'.
Roberts-MacBook-Pro:Flag robertnash$ cd .build
Roberts-MacBook-Pro:.build robertnash$ cd debug
Roberts-MacBook-Pro:debug robertnash$ Flag
-bash: Flag: command not found
It must be a path, like so.
Roberts-MacBook-Pro:debug robertnash$ ./Flag
Why is that ?
If you run export PATH="$PATH:." then it will add the current working directory to your path and you won't need the ./ prefix. (Most (all?) shells accept just a trailing colon without the dot, but I find it's more explicit about what it does.)
This isn't present by default because it is a security risk: a malicious script could be named as something missing from your path, like nmap or even as a typo like sl, and placed in a directory in the hopes that you run it. Forcing you to prefix ./ is a good way of avoiding that.

closure compiler output on the same file not working [duplicate]

This question already has answers here:
Use Closure Compiler Command Line Minify and Replace Original File
(2 answers)
Closed 8 years ago.
I try to override my source file with compiled version at build time.
java -jar compiler.jar --js test.js --js_output_file test.js
the above command succeed but the content of test.js gets wipped out.
If I output to a different file then it works.
What should i do to make it override the same file with minified
version?
try:
java -jar compiler.jar --js test.js > test2.js; mv test2.js test.js

How to compile several files to the same ones

I know that Google Closure Compiler allows me to compile several files into a single one like the following:
java -jar compiler.jar --js assets/js/file1.js
assets/js/file2.js --js_output_file assets/js/file.min.js
But I need to compile files and put it to the same name in the same folder like this:
java -jar compiler.jar --js assets/js/file1.js
--js_output_file assets/js/file1.js
java -jar compiler.jar --js assets/js/file2.js
--js_output_file assets/js/file2.js
But it doesn't work. The files get corrupted. Can you help me?
First and most importantly, your compile script is set up to overwrite your source files. Are you really, absolutely positive that this is what you intend to do? Compilation is a lossy transformation: it destroys comments (including type annotations), renames everything, refactors aggressively, inlines everywhere, and generally purees your hard work into an unmaintainable mess.
java -jar compiler.jar --js assets/js/file1.js
--js_output_file assets/js/file1.js
java -jar compiler.jar --js assets/js/file2.js
--js_output_file assets/js/file2.js
If I am to take you at your word and you have actually done the above, this would unfortunately explain your "my files are now corrupted" question. I hope you have a backup.
More generally, grok the Compiler Manual. All of it, but especially the section on inconsistent property names. If the compiler is not informed about how your source files relate to eachother, it is impossible for closure to rename their contents consistently.
If you intend to create pre-compiled .dll style shared objects, this is not supported by closure because of the name-fragmentation issues documented in the manual. Also, there's no need to pre-compile, compilation is reasonably fast as-is. Share your source files instead.
Please, please make yourself a build directory and pipe your compiler output away from your source code. Code never builds perfectly on the first pass. Even if the code in question is a simple math utility, you'll want to build and test more than a few times.
In summary:
(1) read entire manual, (2) write Externs or try goog.require, (3) pre-compilation is overrated, (4) never ever ever overwrite source files ever, (5) keep frequent backups.
Simply use multiple "--js" params in command line:
java -jar compiler.jar --js 1.js --js 2.js --js 3.js --js_output_file all.js

The logic of the ocaml compile process

I wrote a small project in OCaml.
I have two folders:
./myUnionFind. inside there is a file myUnionFind.ml.
./percolation. inside there are two files: myPercolation.ml and percolation_stats.ml.
myUnionFind.ml works as a module.
myPercolation.ml works as a module too, but it uses MyUnionFind module defined in myUnionFind.ml.
percolation_stats.ml uses myPercolation.ml.
together with above all, I also use Batteries.
I want to compile them all to work and get a executable file run.
But how?
I have tried the following:
inside folder ./percolation, I did ocamlfind ocamlc -package batteries -linkpkg ../myUnionFind/myUnionFind.ml myPercolation.ml percolation_stats.ml -o run
It failed, and said File "myPercolation.ml", line 1, characters 0-16:
Error: Unbound module MyUnionFind, but I did include that folder ../myUnionFind, right?
Also, if I just want to compile ./myUnionFind/myUnionFind.ml once, how can I do so that not every time, myUnionFind.ml gets compiled again and again?
Inside myUnionFind, you should compile myUnionfind.ml to a compiled unit:
cd myUnionFind
ocamlc -c myUnionFind.ml
This will generate myUnionFind.cmo, which stores the compiled implementation, and myUnionFind.cmi, which stores the compiled interface. Other modules using MyUnionFind will need to access the cmi at type-checking type.
Inside percolation, you can compile myPercolation.ml to a module by doing
cd percolation
ocamlc -I ../myUnionFind -c myPercolation.ml
Again, you get both a .cmo and a .cmi. Note that the compiler has looked up myUnionFind.cmi automatically in the search path, and found it because of the -I option.
You can then compile percolation_stats (relying on both previous compilation units)
ocamlc -I ../myUnionFind -c percolation_stats.ml
You finally link the three resulting .cmo together to build an executable:
ocamlc ../myUnionFind.cmo myPercolation.cmo percolation_stats.cmo -o run
(If you use batteries, wrap each command with ocamlfind ocamlc -package batteries, but only the linking command with linkpkg).
To make this process simpler:
ocamlbuild is good at finding and compiling all the files of your current project to produce an executable. In the percolation directory, ocamlbuild percolation_stats.byte can produce an executable with all the stuff present
but if you want to use myUnionFind as an external library, the best thing to do would be to install it with findlib, to make it easy to find and specify from percolation; for information on how to create a findlib package (it's very simple), please see this older answer
once myUnionFind is a findlib package, the single command ocamlbuild -use-ocamlfind -pkgs batteries,my-union-find percolation_stats.byte (or .native) should be enough to get an executable

Resources