How to implement error tracking in a polymer? - javascript

Is there a way of error tracking in Polymer?
Problem is that apparently vulcanize and polybuild processes couldn't provide any source-maps (Please correct me if I'm wrong). That means that even if I will catch an exception in vulcanized java script code using global window.onerror function I will be not able to map it back and find an actual location of an error in a source files.
any solutions/workarounds would be highly appreciated.

Here is my idea of what could be done. Please provide your ideas and solutions aswell. This solution is not tested.
according to https://github.com/PolymerLabs/polybuild polybuild tool is the same as:
vulcanize --inline-css --inline-scripts --strip-comments index.html | polyclean | crisper --html index.build.html --js index.build.js
the order is:
1) vulcanize produces one html formatted file.
2) polyclean uses uglifyjs internaly and perform some cleaning
3) crisper is used to separate already uglyfied and minified js from html
as far as I know uglifyjs doesn't work with html files as input so polyclean manually cuts parts of js code', put it through uglifyjs and paste it back (I hope I understood correctly how polyclean works). That's why creating of source maps is useless in this context.
my idea is to change the order of polyclean and crisper and modify polyclean to allow using external options for uglifyjs2:
new order:
1) vulcanize produces one html formatted file.
2) crisper is used to separate formatted js from html.
3) polyclean uses uglifyjs internaly and perform some cleaning (in this case we need to use on both js and html files)
So first you will have html file and formatted js file and only then you can use uglifyjs2(call from polyclean or standalone?) with --source-map and --source-map-include-sources options.
Now you can keep tracking your errors using produced source-map which already contains formatted copy of js file produced in step #2.

Related

Prevent default addition of deps.js

I am trying to use google closure library for my web app's javascript. I have my JS script in static directory along with closure library:
static/
app.js
closure-library
JS code is combined into a single script using closure builder:
static/closure-library/closure/bin/build/closurebuilder.py \
> --root=./static/closure-library/ \
> --namespace="pr" \
> --output_mode=script \
> --output_file=./static/app-calc.js static/app.js
The backend is in Go. Script generated above is included in HTML as:
<script src="/static/app-calc.js"></script>
However, as soon as the page is loaded, deps.js is added to DOM after the above script tag:
<script type="text/javascript" src="deps.js"></script>
Since this file is added without any preceding path, browser this to load this script using current application URL.
Is there any way to change this behavior or prevent addition of deps.js?
As far as I can tell, since the entire library has been combined into a single file, there shouldn't be a need for this file. Closure docs about depswriter mention path being same as base.js, but since base.js is not even included, I don't see how that's suppose have any to effect on applicaton.
Closurebuilder is deprecated and you should use closure compiler directly instead. See How to use Google Closure compiler which covers many of your questions. The wiki page about Managing Dependencies has current details. Note that there is still a lot of old documentation about closure compiler that has not been updated for example https://developers.google.com/closure/library/docs/closurebuilder. Some of those pages are still relevant but others are out of date. The wiki at github is all up to date.
The deps.js file is only needed now for debugging when running directly from source code (without compiling). See https://github.com/google/closure-compiler/wiki/Debugging-Uncompiled-Source-Code.
The compiler will be able to take just the pieces of closure-library that you are using and combine it with your code.
Set a global variable or global object property "CLOSURE_NO_DEPS" to true. This will prevent base.js from attempting to load the deps.js file.
Details can be found in the code:
https://github.com/google/closure-library/blob/master/closure/goog/base.js#L19

Understanding the Communication between Modules in jQuery Source Code Structure [duplicate]

Uncompressed jQuery file: http://code.jquery.com/jquery-2.0.3.js
jQuery Source code: https://github.com/jquery/jquery/blob/master/src/core.js
What are they doing to make it seem like the final output is not using Require.js under the hood? Require.js examples tells you to insert the entire library into your code to make it work standalone as a single file.
Almond.js, a smaller version of Require.js also tell you to insert itself into your code to have a standalone javascript file.
When minified, I don't care for extra bloat, it's only a few extra killobytes (for almond.js), but unminified is barely readable. I have to scroll all the way down, past almond.js code to see my application logic.
Question
How can I make my code to be similar to jQuery, in which the final output does not look like a Frankenweenie?
Short answer:
You have to create your own custom build procedure.
Long answer
jQuery's build procedure works only because jQuery defines its modules according to a pattern that allows a convert function to transform the source into a distributed file that does not use define. If anyone wants to replicate what jQuery does, there's no shortcut: 1) the modules have to be designed according to a pattern which will allow stripping out the define calls, and 2) you have to have a custom conversion function. That's what jQuery does. The entire logic that combines the jQuery modules into one file is in build/tasks/build.js.
This file defines a custom configuration that it passes to r.js. The important option are:
out which is set to "dist/jquery.js". This is the single
file produced by the optimization.
wrap.startFile which is set to "src/intro.js". This file
will be prepended to dist/jquery.js.
wrap.endFile which is set to "src/outro.js". This file will
be appended to dist/jquery.js.
onBuildWrite which is set to convert. This is a custom function.
The convert function is called every time r.js wants to output a module into the final output file. The output of that function is what r.js writes to the final file. It does the following:
If a module is from the var/ directory, the module will be
transformed as follows. Let's take the case of
src/var/toString.js:
define([
"./class2type"
], function( class2type ) {
return class2type.toString;
});
It will become:
var toString = class2type.toString;
Otherwise, the define(...) call is replace with the contents of the callback passed to define, the final return statement is stripped and any assignments to exports are stripped.
I've omitted details that do not specifically pertain to your question.
You can use a tool called AMDClean by gfranko https://www.npmjs.org/package/amdclean
It's much simpler than what jQuery is doing and you can set it up quickly.
All you need to do is to create a very abstract module (the one that you want to expose to global scope) and include all your sub modules in it.
Another alternative that I've recently been using is browserify. You can export/import your modules the NodeJS way and use them in any browser. You need to compile them before using it. It also has gulp and grunt plugins for setting up a workflow. For better explanations read the documentations on browserify.org.

How to compress json files into javascript

I am making a browser game (client side only). I am trying to make it smaller (meaning file sizes), which is first step for mobile version. I have minified CSS using LESS, JS using uglify and also angular templates using grunt-angular-templates. So at this moment I am loading very small number of files:
index.html
app.js
app.css
images.png (one file with all images)
But the remaining problem are JSON data files. There are (or will be) many levels and each level has its own JSON data file. Also there are some rule definitions etc. The problem is, that these JSON files are loaded dynamically when needed.
I am now trying to find a way, how to somehow get these files (at build time, probably some grunt task) into one file, or even better - directly into app.js. I have no problem in writing PHP script + JS class, that would do this, but I first tried to find some finished solution.
Does anybody know about something like that, or is there any other solution that I am not thinking about? Thanks for any help.
====
EDIT:
1) The point of this is getting rid of X requests and making one request (or zero) for JSON files.
2) The compiled thing does not have to be JSON at all. Part of my idea:
JsonManager.add('path/to/json/file.json', '{"json":"content of file"}');
making all these lines manually is bad idea, I was asking about something, if there is anything, that could do this job for me.
3) Ideally i am looking for some solution similar to what grunt-angular-templates task does with HTML templates (minifies them and adds them to app.js using Angular's $templateCache)
Say you have two JSONs: {'a':1} and {'b':2}.
You cannot simply concatenate them into one chunk as together they will not be a valid JSON, e.g. this {'a':1}{'b':2} is not valid JSON. You can do this with JS and CSS but not JSON.
The only option is to include them into larger structure:
[
{'a':1},
{'b':2}
]
If your code structure allows to do this then you can use any existing JS compressor/uglifier to compress the result.
For anybody who has same problem as me:
I gave up finding already finished solution, and made my own:
The solution
I have written PHP script, that iterates over files in data directory and lists all JSON files. It also minifies their contents and creates one big array, with keys as relative file names and values as JSON content of files. It then creates a .js file, in which this big array is encoded as JSON again and given to a JavaScript variable (module constant in my case - Angular)
I created a wrapper class, which serves this data as files, e.g.:
var data = dataStorage.getData('levels/level01.json'); // returns JSON content of file located at path/to/data/files/levels/level01.json but without any AJAX call or something
I used grunt-shell to automate running this php file
I added the result .js file to list of files, which should be minified by uglify (and connected together).
The result:
I can create any number of JSON files in any structure and link to them from js code using that wrapper class, but no AJAX calls are fired.
I decreased number of files needed to load at startup (but increased app.js size a bit, which is better than second request).
Thanks for your ideas and help. Hope this also helps someone

How to disable the JavaScript Minifier in CodeKit?

What's the best way to disable JavaScript minification in CodeKit? All those *-ck.js files it creates are making a mess of our repository's submodules.
Note that adding a rule to .gitignore doesn't work because its rules aren't inherited by submodules.
In CodeKit Preferences select Languages / JavaScript to edit the default settings for JavaScript handling. (These can be overridden for each file in a project.)
Change the setting for the second processing step (labelled "Then:") from "Concatenate + minifiy" to "Concatenate imported files". For any script file already in the project check whether it already has individual settings which still differ from this new default.
In this case, "*-ck.js"-files should only be created in case a source file imports another for concatenation but not for ordinary script files.
Alternatively you might specify a different output path for the generated ck-Files in CodeKit Preferences / JavaScript / Output Paths in order not to let the generated files clutter the source directory.
I believe the menu has been updated, but the answer from immo still stands. Under Javascript Language settings you can click a dropdown for output style and change it from minified to non-minified.
One workaround is to set the output path to something like codekit-ignore in Preferences > JavaScript > Output Paths, relative to the project's root folder.
Then add /codekit-ignore to .gitignore.
Easy to cleanup and feels better than find . -iregex '.*-ck\.js' -delete.
In the preferences see 'Skipped Items' under 'General' and add *.js to the list.
There are several ways to stop javascript minification in Code Kit but the easiest and simplest way to do so is simple to navigate to the javascript file you wish not to minify in the file view, and configure your Javascript Options to the right hand side.
This method provides benefits such as JSHint & JSLint without the minification and can be configured on a site by site, file by file basis giving you greater control.
Let me know if you have any further issues, i'd be happy to help.

Google Closure Templates generates multiple JavaScript files for each language instead of single JavaScript code base with separate resource files

I'm using Google Closure Template in order to write my application's UI using JavaScript. Look at this question for the detailed reason of why I'm using Google Closure Template. I want it to be multilingual. I see that there is a --locales switch and also looked at the samples provided in the project here and here. In the README_FOR_EXAMPLES files it is written that
+ simple_generated_en.js, features_generated_en.js,
simple_generated_x-zz.js, features_generated_x-zz.js
The JS files generated by SoyToJsSrcCompiler when it is executed
on simple.soy and features.soy (locales are 'en' and 'x-zz' with the translated XLIFF files from shared examples directory 'examples' and with the above compile-time globals
file). We need both simple.soy and features.soy because some of the templates in features.soy call the templates in simple.soy.
Note: For an example Ant target (and command line args) that
generates these files, please see target 'js-features-example' within the top-level 'build.xml'.
What I expected was that it would generate just one JavaScript code base which will use desired strings from the appropriate locale file based on an option provided at runtime before the template function is called. Is that possible with closure templates?
As far as I can see, you can use a dictionary-object as a parametr for your template.
/**
* #param dict
*/
{template .example}
<h1>{$dict.title}</h1>
<div>{$dict.content}</div>
{/template}
This object can be generated on the server-side from your locale file and transfered to javascript via script tag.
Otherwise you can load different compiled template file to the client side according to the locale.
There's also i18n possibility, but it's kinda useless for your problem, imo.

Categories

Resources