I keep getting errors that the function (renamed) does not exist for the given object. Is there a release or setting or something to make it work?
You must use an externs file for jQuery when using Closure Compiler Advanced Mode with jQuery. Extern file will tell compiler these are reserved methods and accept these argument and argument data types should be like that, so do not minify method names and check argument data types in that way.
You can get externs file which is created by Google Developers here. This file generated for jQuery-1.4.3. But currently probably will work any version of jQuery. Newly added methods may not include in that file, so you should add it to externs file, syntax and synonyms are so simple.
Also you can say location of externs file to compiler by using an extra compier flag. Syntax should be like this
--compiler_flags= "--externs=path/to/jquery.externs.js"
Also you can use this tool which is an online externs extractor for Closure Library.
You have to declare jQuery as an extern to the compiler...however I'm not sure if anyone's made one, there was an extern file for 1.3.2, but I haven't seen any 1.4+ versions.
Edit: this issue thread here has the community building a 1.4 version.
jQuery is not compatible (yet) with the Closure Compiler in advanced mode. I agree it would be a very good thing to make it compatible, because its method-chaining syntax lends very readily to prototype virtualization for much improved execution speed.
In fact, among the popular JavaScript libraries (other than Closure Library, that is), only the Dojo Toolkit is compatible with Closure Advanced mode.
http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t
Related
I am building a clojurescript application that depends on react-apollo to interact with third party graphql API. Since I could not figure out a way to load the library with all dependencies externally, I opted to npm install it and let the whole dependency get compiled by closure compiler. This did not work out of the box and required fork-and-patch on some js dependencies that confuses google closure compiler due to mix of ES6 and CommonJS require/import.
With advanced optimization, I was only able to get things working after fishing out renamed properties in the js debugger. And I'm sure my extern file does not have everything. I also need to make sure all properties are addressed by string in clojurescript, I think graphql creates object based on string in the query.
With string keys, things like destructuring don't work. Transforming objects with js->clj :keywordize-keys true and back seems to rename properties unless I add every keyword to the extern file.
I tried setting *warn-on-infer* and :infer-externs, but the generated extern has very few entry. Not sure if I'm using it right.
Advanced optimization seems like a must though, it's 461K vs 3MB with simple.
TL;DR
Tried to use npm lib in cljs, issues with advanced optimizations. What is the best practice to use these libs?
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.
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.
Does anybody have to share a file for extern definitions for dojo and dgrid ?
I am trying to include those in my clojurescript project and to use even 'simple' clsure compiler optimization option.
At the moment I have found dgrid and dojo toolkit incompatible with Clojurescript compilation process.
In other words it is not possible to
a) include dojo or dgrid with :foreign-libs option and then leverage the
closure compiler to create a 'minified release using closure compiler :advanced or even :simple option
b) it is also not possible to include the dojo or dgrid libraries with :extern option
because for that one has to create a list of extern definitions (which does not come in dojo/dgrid releases).
I am pretty sure option ( a ) is a dead-end, because for it to work dojo team needs to make changes to the toolkit, and it is probably low priority. I have read Stephen Chung's 50+ pages document of how to modify dojo to work with google-closure, but it is well beyond my capabilities to re-implement for Dojo 1.9 and above.
I am thinking ( b ) might eventually work, but for that I need to find the externs library.
Hoping somebody has done it for dojo 1.9 and the latest dgrid.
Prior to posting here I had checked the repository of currently available 'externs' for the closure compiler,and dojo is not there
https://code.google.com/p/closure-compiler/source/browse/#git%2Fcontrib%2Fexterns
I had also found a online extractor of externs
http://www.dotnetwise.com/Code/Externs/index.html
and http://www.dotkam.com/2013/07/15/clojurescript-use-any-javascript-library/
However, I am not even sure what dgrid/dojo files to do this for.
Therefore looking if anybody has created these externs already.
You can use their own source file as the externs definition. Obviously this means that the compiler can't optimize the library, but if as you say, you don't need that, it's a good working option.
I am not experienced with dojo/dgrid in ClojureScript but I've used several javascript libraries with ClojureScript already.
The best way to use complicated libraries with ClojureScript is just not to touch them, and not run Google Closure on them. (what you call (b)).
Therefore, you will need to put very few externs definitions in externs.js
Only for the specific vars/functions which you access from your ClojureScript code. You don't need externs.js for EVERYTHING they declare.
The Google Closure compiler will run only on your code, not the external js library.
You need to put externs only when you:
1. Call your cljs function from js code (to avoid calling a munged function name that is not what you have in your js)
2. Call the js library function from your cljs code (to avoid having munged the function name in the function call).
So there's no prior work that needs to be done, you need to put a small externs file exactly for the specific calls you make.
I have a JavaScript library that I am working on currently. I have structured it into lots of files and I use the module approach to define each 'module'.
var ns = generateNamespace("me.mycompany.mypackage.MyFile");
(function (ns, undefined) {
// some module
}(ns));
The modules are dynamically named using a namespacing function meaning that autocomplete is almost impossible as things stand (unless Eclipse can run my code and figure out the namespaces, Visual Studio can!).
Therefore I intend to generate JSdoc for my project in the hope that if I include this into Eclipse (somehow) Eclipse can use this to give me content assist.
Firstly I do not know if this is possible... however I think that it is as I can see that it is maybe how this works? However I tried to follow this along and struggled to get something working, by this I mean it didn't work. The interesting info from the link:
"JSDT libraries are collections of JavaScript source files that have prototyped object/class definitions and JSDoc. The inference engine then models these libraries... making them available to every JavaScript file in the project... Bindings for nonstandard and future runtimes are similarly easy to create... add the... library to their project and gain content completion and hover help"
I know how to write JSdoc annotations and I know how to generate JSdoc using one of the various tools.
What I need therefore is instructions on how to include JSdoc (as a library maybe) in Eclipse so that it will give auto complete for the stuff in the JSdoc.
Previous answer:
You can also run jsdoc_toolkit from within eclipse by setting up Run -
> External Tools -> Open External Tools Dialog...
Location
C:\Program Files\Java\jre1.5.0_12\bin\java.exe
Working Directory
C:\DirectoryToWhereJsDocToolkitIsLocated\jsdoc_toolkit
Arguments
-jar app/js.jar app/run.js -r=4 -t=templates/htm "-d=C:
\PathToWhereDocIsSaved" "C:\PathToWebsiteToDocument"
For more about the arguments check the jsdoc_toolkit documentation.
Have fun
Simon
Taken from this Google Groups thread.
Updated Answer:
Eclipse JavaScript Editor: content assist for js files, autocompletion
Disclaimer, I'm the author of tern.java.
I suggest you that you install tern.java. It provides a JSDoc support. Once you have selected this support, you can benefit
with completion :
and soon with validation:
This support is not perfect but it starts working.
I am not using it by myself, so I'm not sure if it works, but there exists a grunt-plugin for jsdoc3. Grunt is supported by Eclipse. So maybe it helps.
Grunt-PlugIn in npm