Concatenating and compiling uglified javascsript in closure compiler - javascript

For some javascript packages I can only get the minified/uglified file. I need to combine them with my other javascript files and compile with google closure compiler.
My question is:
Is it preferable to pass the raw unminified javascript to closure compiler, instead of the uglified one? (in particular with the advanced optimization mode.)
Since many javascript library provide minified version itself(like jquery and angularjs), do I need to worry if I included those scripts in another minification task(uglify or closure compile). Or should I single them out and only concatenate them?

If micro-optimisation is your thing, you might want to have a look at several minifiers to see which is the best fit for your codebase. The main ones are UglifyJS, Google Closure Compiler and ESMangle. There's a nice comparison on the Uglify website. Running code through several minifiers may seem like overkill but if it yields better results then why not. :-)
Minifiers don't care if you pass in something thats already been minified; as an example I use the r.js optimiser in production, and that concatenates my unminified source code and minified jQuery and the like, then uglifies the whole lot.
You don't need to really worry about reminifying libraries, all it's going to do is add more time onto the build step, so if it's taking too long then you could split out the libraries from the minifier and simply concatenate them.

There are two paths depending on the library:
If the library provides the unminified source AND it is known to be compatible with ADVANCED_OPTIMIZATIONS then the best option is to pass it in as a source file. This option reaps the benefit of dead code elimination on the library source as well as your source.
If the library only provides the minified source OR is known not to be compatible with ADVANCED_OPTIMIZATIONS, then the best option would be to compile your code using externs for the library. For minimizing the number of requests, you should still concatenate the results together. While you could use the WHITESPACE_ONLY level of the compiler, it may not be the best tool for that.
Of course combining a library with your source will minimize requests, but will at the same time nullify any caching benefit from using a CDN for the library hosting.

Related

Compiling Typescript to use as a JSFL script

So at my job I need to write a lot JSFL scripts. And because of the way JSFL, the scripts tend to be gigantic files, with functions and spaghetti everywhere.
So I had an idea to write them in Typescript, using separate files as "modules" (like I'm used to for commonjs/es6). And compile that all down to a single file.
I've tried searching but I've been unable to come up with an answer. Since JSFL just expects a simple javascript file. I obviously can't use commonjs, amd, etc.
So is there a way, that when developing. I can write separate "modules", have typescript (or if needed webpack) compile them into a single javascript file? Just like copy the functions from each file, and place it into one big file.
I'm not sure if its possible with typescript, or if I'll have to use some script or something to extract all the functions out.
Also since Adobe's JSFL is using an ancient javascript engine, it doesn't support a lot of features, and I will be adding polyfills to fill those holes.
You can use the typescript compiler option --outfile
Concatenate and emit output to single file. The order of concatenation
is determined by the list of files passed to the compiler on the
command line along with triple-slash references and imports. See
output file order documentation for more details.
See also documentation.

In VS, is there a way to ignore errors on some typescript files but still compile them in?

I'm writing a large application with several 3rd party libraries. Right now, I am using a post-build script to concatenate all of my .js files together, along with the output of all my combined typescript files. This works fine, but makes it so the source mappings are off for debugging.
What I'd like to accomplish is converting all of my 3rd party .js libraries into typescript (and by converting, I mean just renaming them from .js to .ts since typescript is a superset). From here, I can just use the typescript compiler to output all of the combined typescript files with accurate source maps so debugging in typescript will still work. However, the issue I'm running into is that the 3rd party libraries have various errors, so I cannot get the build to work.
Is there a way in Visual Studio to have my existing typescript files compiled as they are while having these third party libraries compiled but ignoring all errors and have the result all output into one single javascript file?
TypeScript is able to forgive a whole host of errors and still provide compiled JavaScript, but in some cases the error will prevent it - i.e. the code will no longer make sense to the compiler because it cannot determine enough information.
The solution would be to splatter lots of : any type annotations to suppress errors.
The real danger with your approach will be trying to keep your edited versions of all of the libraries updated as they change.
Here is an alternative...
Combine all of your third party libraries into a single file, then combine all of your TypeScript files into a single file (so your source maps work).
This will allow you to easily debug and you could always crush the two files together later if the extra HTTP request worries you.

Should I concatenate/minify already minified JS/CSS? If so, how?

Our app has several JS library dependencies which are already minified. We're considering concatenating them into a single file to reduce the volume of separate threads the browser needs to download them all.
The minifiers I've looked at so far don't handle this well (examined Google Closure Compiler, YUI Compressor). I don't really need my already minified libraries minified again. What is the standard practice for this in the JS world? And do I need to worry about specifying order?
Question is similar for CSS. These libraries provide pre-minified CSS, which I'd like to concatenate together.
You typically wouldn't minify code that is already minified. If the provided minified library was minified in a bad way (like packer), it would be better to minify the original library source code using your favorite minifier.
In your case it's better to look at concatenation only.
You can do this using Gulp or Grunt. Both are able to generate sourcemaps.
I have not had any trouble with use strict when concatenating multiple libraries to a single file, but it is something to pay attention to. Properly written libraries apply use strict only to their library scope, to not affect the global scope / other libraries.
If some silly library applies use strict to the global scope, and another silly library is not compatible with strict, Firefox (probably Chrome as well) throw a strict violation error immediately, so this error is easy to spot.

How to distribute a library which uses Closure-library without including any of the actual Closure-library source?

I've recently created a JavaScript library using Google's Closure Compiler: https://github.com/bvaughn/task-runner
I intend for this library to be used by applications that also require the full Closure Library, and so I want the built version of my library (Task Runner) not to include a subset of Closure Library. If Task Runner includes a subset of Closure Library, and another application includes the full Closure Library, a race condition will exist between which loads Closure last (last in wins). It also bloats the size of the Task Runner file.
However I'm having trouble. If I don't require any of the Closure library classes, Task Runner builds fine (obviously). However if I require something (goog.dom for instance) then my "compiled" JavaScript file also includes a portion of the Closure library. Is there a way to tell the Closure Compiler to leave certain JavaScript files/modules/whatever out of the built result?
FWIW, the Plovr experimental-exclude-closure-library option seems to somewhat describe the functionality I'm looking for.
On the surface what you are asking makes no sense. You want to depend on/use code from Closure-library, but not include it in your output. This isn't really possible nor how the library and compiler function together.
There is a rather small list of primitive functions defined in Closure-library that are completely removed/replaced when compiled with Closure-compiler. goog.require and goog.provide are the two most prominent of those.
For the vast majority of the Closure-Library, if you use or depend on a class, method or object that specific code will appear in the compiled output. And because that library code itself may depend on other parts of the library, even more code may be included in the compiled result.
The difference between using Closure-compiler with Closure-library as compared to more traditional JavaScript libraries is that ONLY the parts of the code determined to be called and used are included in the output. This is much more granular than a simple file inclusion - prototypes, variables, constants, etc will all be excluded because the compiler can determine that they are never used.
Distributing a Library
If you are building a library which depends on Closure-library, you have two options.
Distribute a compiled/built version
You would compile your library using Closure-library; exporting any public API methods and properties. Others who utilize your library with Closure-compiler or Closure-library will need to use an externs file and include your library AFTER compilation.
Distribute your library as source
You would simply distribute your library source code. Others would goog.require your library as part of their source and build process. If Closure-library is used in both projects, it will only be included once in the build process.
There is no hybrid approach where you compile your code but exclude Closure-library. This violates the principle that all of the source code will be compiled simultaneously.
You can peruse my Geolocation-marker library to see an example. I provide a compiled standalone version of the code for use, but the uncompiled source can also be included in other projects which use Closure-library.

What is the behavior for referencing javascript libraries multiple times across multiple files?

I have some javascript files that I want to live independently of each other. Each of these files reference other files for some library functionality.
Finally, there are times when all of this code can be used at the same time. I know that referencing a javascript file is not equivalent to a c++ include or java import. Is there a way to achieve that kind of behavior?
For performance reasons you probably should concatenate them all into one. Compress that one using Google Closure and then serve it as a single and cacheable file.
I don't know about any native interface specification in Javascript. You "only" need to make sure the things you reference/access are already loaded. This may become messy if there are lots of dependencies.
That's why big JS-frameworks have some code for module loading and dependency specification.
Libraries I would name here are head.js and RequireJS.
But think what size of tool you really need.

Categories

Resources