ClojureScript-Lib and my ClojureScript on same page - javascript

Let's assume I have a small web-application and want to use a third-party library that comes with an already compiled version of a ClojureScript.
As a user of that library I have to include that generated Javascript file in my HTML page.
<script src="/javascript/gen/lib.js" type="text/javascript">
So far so good. Everything works fine.
But since my web-application needs some frontend-magic, I wanted to include some ClojureScript of my own. So I wrote a couple of lines, compiled it to Javascript and added another line in the HTML head:
<script src="/javascript/gen/lib.js" type="text/javascript">
<script src="/javascript/gen/my-stuff.js" type="text/javascript">
This is, where it gets ugly. I get this error in the javascript console:
Error: Namespace "goog.debug.Error" already declared.
After googling that error, I get multiple pages, that state, that I can not use multiple Google Closure Compiled things on one page. See SO: Multiple ClojureScript files on same page
So, how do I tackle that situation? On one hand I have an already Google Closure compiled lib and on the other hand my ClojureScript stuff. How do I get one (or two) compiled Javascript files out of this?
Would it be easier, if that third-party lib would provide a non-compiled ClojureScript version?

Yes, it would be easier if the third-party library would provide a non-compiled ClojureScript version. Then you would require it and use it from your code and compile everything together. The ClojureScript compiler with require each dependency once (even the shared dependencies) and the Google Closure compiler would do its optimization pass over all the code.
Try to find the library in Clojars or package it as a jar to consume it from your existing ClojureScript setup. (If the library is open source, give us a link and we'll help you out)

Related

Using Google maps Javascript API the good way

I am trying to follow the practice of compiling all my javascript files and js plugins etc into one single javascript file, which then gets included into my website. So far I have been using gulp with npm for this purpose, but I am really struggling when it comes to the point that the libraries I want to include don't work like that. For example Google Maps API. So, how can I deal with such cases ? I have been asking around and I hear that there is not a way to "include" a javascript file like you can include a php file, but is this the final answer ?
I know you can include other files with jQuery on runtime, but that way you are not avoiding the additional http calls, remember the ideal case is to call one javascript file which has all the js code you need.
Even when I am using require in javascript, the required file must have a proper format and I have to assign it to a variable bla bla bla, but when I include a script like this <script type="text/javascript" src="myjsfile.js"></script> everything is included in my scope properly.
How can I work around this ? Would it be a good practice if a javascript compiler like gulp copied the contents of all my javascript source files and pasted them into one single merged file ? Wouldn't that work the same way as calling all those files with ?
Well, I started this question because I am having troubles with the google maps api, but the problem is more general, so if you can help me please answer the above questions too. Anyway in the google maps api case, I am working with it perfectly fine when I include it like this
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MYKEY&callback=Mycallback">
</script>
But how can I merge this into my minified way of including libraries ? I tried to use some npm libraries that integrate with google maps api (like this for example), but I am getting CORS problems and I think this is an expected behaviour.
Thanks in advance ! Sorry if something sounds stupid, I am trying to learn the good way of coding.
Decent question.
I'm not an expert but there is my subquestion/answer:
async attribute lets load html and script(s) simultaneously. If map is main feature of site, I would place <script> on top of loading html file so its not always rule to place in to the bottom of <body>.

How to use minimized version of Ol3 library

I have a problem using the minimized version of OL3 library. It doesn't include the goog namespace. I do not know if it is not included in the js file or is the 'goog' namespace obfuscated.
But this part can be easily handled by just including Google closure library in a separate file. But after I do that I get another two errors:
NetworkError: 404 Not Found - http://localhost/my_test_app/apps/deps.js: should I include this file as well and if yes, should I include all other files from google closure library which this file tries to add dependencies to ?
ol.proj.Units is undefined: this one looks like obfuscated namespaces
And again it also looks like some namespaces were changed.
Shouldn't the namespaces, just like public methods, be kept unchanged in the obfuscated file ?
I tried to use the latest version of OL3: 3.8.2
You should not have to load the goog namespace in production, there is a good discussion with good example of how to create an OpenLayers3 control with plain javascript on the OL3 GitHub. https://github.com/openlayers/ol3/issues/3943
ol.proj.Units is not obfuscated, it is part of the public library. It's value is probably not initialized correctly in your application.

Untangling JS Source from Closure Compiler

There is a javascript application I would like to modify for my use*. The problem is, the js is compiled with Google Closure Compiler. Obviously, I should modify the sources (which are available in the repository), and re-compile.
This is my first encounter with GCC. I skimmed the documentation and came to the conclusion that the key is using the sources mentioned in deps.js via goog.addDependency keywords.
So I set up an HTML file and referenced all the sources. Loading this file I got 118 ReferenceError: goog is not defined errors in firebug console.
Then I read some more and found the app has been compiled with the help of kbuild, and that it uses a config file, config.kb, to send the right parameters to GCC. This file, indicates the first file should be loader.js, so I reordered the <script> tags and moved
<script type="text/javascript" src="./eightball/loader.js"></script>
to the top. but the same errors are thrown. So, what is missing?
* The license is MIT and there is no issue with the rights.
First, it would seem the application is using Google Closure, which is a JavaScript library developed by Google.
This is (of course), completely different to Google Closure Compiler, which is a JavaScript minification and obfuscation engine (dang these large companies and their quest to name everything the same).
That means you should include the Closure bootstrap before deps you've got listed; which is what the application itself does, as in the main view, it calls the game_js helper, which includes the base file of Closure if the application hasn't been compiled.
TLDR:
Try including the /javascripts/closure/closure/goog/base.js file first.

Can I use CoffeeScript to combine other js files?

I'm wondering if I can use CoffeeScript to include other standard JS files (as a simple way to do some combining of files).
I have a client-side minification tool I'm using (an app called Live Reload) which is working just fine.
<!-- Some jQuery plugins I'm using. -->
<script src="/js/libs/some-plugin.js"></script>
<script src="/js/libs/another-plugin.js"></script>
<!-- The output of my /js/script.coffee file: -->
<script src="/js/script.js"></script>
What I'd like to do, is just combine those plugins into output of my coffeescript file. I've looked high and low and I've only seen articles on server methods for this as well as a lot of articles on things like requirejs.org. I'm not trying to do anything that complex- I just want to get rid of a couple round trips for js files I know I'm never going to touch.
Does CoffeeScript have an "include" function to speak of?
There are ways you can achieve this by creating a more complex Cakefile, in which you will read the contents of js-files and append them with CS compiler output than write it into the single target js file. You can even create a fake global require function which will mimic its behaviour in the bundled file.
If you were looking for a standard tool or at least an approach to that problem, unfortunately, since CS is very young, there's none yet. There are some attempts though: https://github.com/jashkenas/coffeescript/wiki/%5BIntegrations%5D-Build-Tools.
I'm currently working on such a tool myself and am planning to publish it within a month. I'll post back then.
Basically, the answer seems to be no. This is not something CoffeeScript is capable of.

gwt separate modules with no code sharing

I have to make a web application using GWT. The project has a core module that'll expose a set of apis to be used by other apps; each of these app are unrelated. Each shall be loaded in a separate iframe.
My idea was to compile core into core.js and each app shall have its own app1.js app2.js and so on...
App1
script type="text/javascript" src="core.js" ></script>
script type="text/javascript" src="app1.js" ></script>
with this design, due to browser caching, each app load only the app.js which should be smaller ~20kb in size.
Making a core module is straightforward but the apps are problematic. The reason being after compilation, each app contains the entire GWT library - this substantially increases the download size of the complete webapp.
Can anyone suggest a way to get around this problem ? I've checked similar questions on SO, but failed to find a simple working answer fr the problem.
It can't be done.
GWT is meant to be a monolithic compile. It will take all your java code, assume that no other code exists other than what was provided to it, and then generate optimized javascript code. While doing so, it will only compile portions of standard GWT library that are actually being used by your program.
Because of the way GWT works, its always going to be inefficient to include multiple GWT modules on the same page.
Instead, here is what I'd recommend -
Have one GWT module per application, not one per page. And putting two modules on the same page is definitely not right
Share java code between modules, not javascript. This means your shared library will never be compiled as javascript

Categories

Resources