gwt separate modules with no code sharing - javascript

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

Related

Why the downloaded web pages have so long *.js files?

I am learning to develop a website.
I am the backend developer but have no experience in this web development.
I have several good references such as https://mvs.org/
In order to see how many lines of code or structure of the web pages, I downloaded the entire web page using Httrack.
I am surprised that a few *.js files include around 60,000 lines of code.
Does it mean that the web developer of the pages wrote that many codes?
or am I missing something here?
It might be a library such as JQuery or React.js, which indeed can include many lines.
Sometimes (usually) all .js files are also bundled into one big file.
Front end development implies different requirements than when one is developing on the backend.
Your context is the browser and you want to reduce the number of HTTP requests as much as possible, thus you generally bundle all your javascript files into one big file using tools such as webpack.
Your code will then be bundled with all the needed npm modules, that's why you end up with one large javascript file.

ClojureScript-Lib and my ClojureScript on same page

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)

Is there a way to provide multiple JS scripts within a single <script> tag?

I am building an app in JQM that has multiple instances but the same core of scripts.
Summarizing, every instance will have its own index.html initializing that particular instance with files both taken from the central repository (the common scripts/interface) and from the particular instance (files specific to that instance only).
Since I am adding more capabilities to the application, I need to constantly update the core of scripts with new addons (both 3rd party or custom scripts), but I don't want to go and update all the single instances with the new scripts I'm adding.
My question is: is there a method to include a <script> tag inside the index.html of every instance (say <script src="commonurl/commonscripts.js"></script>) and on my common repository, in the commonscript.js use structures like the java import, to import all the scripts I'm using?
I know it's not how js works, but the core of the question is: do you have any suggestion on how to keep the client unvaried and work just on the server side modifying just the included file, or anyway not having to manually modify the client index.html? Is js minification/merging my only option?
Same question applies to CSS files included in the client index.html.
Hope this makes sense, thanks for the answers!
You can do this with requirejs
RequireJS is a JavaScript file and module loader. It is optimized for
in-browser use, but it can be used in other JavaScript environments,
like Rhino and Node. Using a modular script loader like RequireJS will
improve the speed and quality of your code.
http://requirejs.org/docs/start.html

How to include external Javascript in GWT offline application

I have a GWT (well, GXT) application that uses an external JavaScript library to add functionality to my app. My application must work offline, too, and herein lies my problem.
I am aware that adding files to the public folder will make them accessible by my GWT app, but this will not work in case of offline use. GWT compiles my app to make it available offline without problem, but it doesn't include the external JavaScript library.
So, whenever I work within the application and reach the point where said library is needed, the browser will attempt a GET request because the library hasn't been loaded yet and doesn't remain in the cache of the browser reliably.
Is there a way to add the library to my app so that it will be cached together with my GWT app? The library consists of several folders, JS files, images, CSS, etc. My only idea is to dynamically create an Appcache Manifest that dumps ALL files in the browser cache.. in which case I'm scared of breaking the GWT offline functionality.
Yes you can generate a manifest at compile time. Just use a linker that extends com.google.gwt.core.ext.linker.AbstractLinker.
See for example this example manifest linker
or see Writing a GWT Linker
or see this stackoverflow thread
I do that to include google fonts and to produce a manifest that will only include files for that specific language permutation.

When to use Requirejs and when to use bundled javascript?

This may be a dumb question for web guys. But I am a little confused over this. Now, I have an application where I am using a couple of Javascript files to perform different tasks. Now, I am using Javascript bundler to combine and minify all the files. So, at runtime there will be only one app.min.js file. Now, Requirejs is used to load modules or files at runtime. So, the question is if I already have all things in one file, then do I need requirejs? Or what is a use case scenario where I can use requirejs and/or bundler?
Please let me know if any further details are needed.
Generally you only use RequireJS in its loading form during development. Once the site is done and ready for deployment, you minify the code. The advantage here is RequireJS knows exactly what your dependencies are, and thus can easily minify the code in the correct order. Here is what it says on the RequireJS website:
Once you are finished doing development and want to deploy your code for your end users, you can use the optimizer to combine the JavaScript files together and minify it. In the example above, it can combine main.js and helper/util.js into one file and minify the result.
This is a hotly contested issue among many proficient javascript developers. Many other languages have a "compilation" phase where the entire program is bundled up for deployment (JBoss's .WAR files come to mind). Programmers that come from more traditional backgrounds often favor this approach.
Javascript has seen such growth in recent years that it is difficult to chart exact best practices, but those that appreciate the more functional nature of Javascript often prefer the module loading approach (like require.js uses).
I wrote Frame.js which works much like require.js, so my bias is towards the module loader approach.
To answer your question directly, yes, it is one or the other.
Most that argue for packing your scripts into a single file believe it enables more compression and is thus more efficient. I believe the efficiency advantages of packaging are negligible in most cases because: (1) module load times are distributed over the entire session, (2) individual modules can be compressed to nearly the same percentage, (3) individual modules can be cached by the server and routers separately, and (4) loading scripts only when they are needed ultimately allows you load less code for some users and more code overall.
In the long run, if you can see an advantage to dynamic script loading use it. If not, bundle your scripts into a single file.
It depends on your application. If you're making a server-side app with only modest javascript (less than 100kb minified) then go for total bundling, you're probably going to be fine.
But if you're making a javascript app and have a ton of code in it, then your needs are going to be different.
For example, in my app I bundle all the core files. There's jQuery, underscore, backbone, my main app files, my user login system, my layout system, my notifications and chat system, all are part of my big initial file.
But I have many other modules as well that isn't part of the initial bundle, that are loaded after those.
The forums, the wiki, the wysiwyg, color picker, drag/drop, calendar, and some animation files are part of the second category. You need to make reasonable decisions about what's commonly used and needed immediately vs what can be delayed.
If I include everything immediately I can get above a meg of javascript, which would be insane and make the initial boot unacceptably slow.
The second category starts downloading after initSuccess event fires from the initial file.
But the second category is more intelligent than the first in that it loads what's more important first. For example if you're looking at the wiki it'll load the wiki before it loads the color picker.

Categories

Resources