ASP.NET MVC: Javascript error logging in production environement - javascript

There are several libraries available for javascript error logging in a web application. These libraries sound useful during development. We can catch javascript errors at global level using widows.onerror handler.
All looks fine and dandy upto this.
But if we enable bundling and minification in ASP.NET MVC, it becomes hard to spot the actual error since minification causes renaming variables and compressing code thereby changing line numbers. How to deal with such a scenario? I've gone through many posts but couldn't find any satisfactory solution. We want the sensible javascripts errors to get logged in production environment. Any thoughts or suggestions on this?

Check out JavaScript source maps, which create a reference between your source scripts and the minified script that get's delivered with the page. It looks like someone has built an extension to the ASP Bundles that enable sourcemaps to be created.
However, even with sourcemaps the errors that are captured from window.onerror will still contain the minified names and locations. You will need to write some code in your error management system to apply sourcemaps to the code (or do it manually) to see the real numbers.
Chrome will automatically apply sourcemaps to errors in its debugger if they are publicly downloadable, but these values are not available programmatically to your error capture.
One last thing to consider is using a hosted service that already solves this problem. You can send error reports elsewhere and have them capture error information and give you reports/alerts about when an important error is happening--and even translate the error with sourcemaps. I recommend (and helped write) TrackJS.

Related

How to have web page include all js files in a directory tree?

I'm trying to figure out how to set up a JavaScript development project that will allow me to factor my code into several files. I plan to run this eventually on a client web browser, but first I need to set up an efficient development environment.
I've used other programming languages before that let you keep a large number of files in a subdirectory and then let you compile everything into your final deployable (or have an interpreter do something similar). Javascript doesn't seem to allow this - I have to manually add a <script> tag for each js file to the head of my web page to get the browser to load it. This can get very hard to manage once you have more than about 10 files that you need to keep track of. It would be nice if I could write <script src="myscripts/**/*.js"> to suck in everything, at least during development time.
I've found Grunt 'uglify' which looks like it would be a handy tool for creating a final file for deployment, but during development I need to keep everything separate so I can debug properly. Is there any way to have my web page load every js file in my development directory?
As others have mentioned in comments, Webpack (or similar) is the way to go. It bundles up all of your relevant code, and can also process it for minification.
I want to address this comment though:
but during development I need to keep everything separate so I can debug properly
You don't need, or want, that. While developing, you want to be testing against the same sort of build process you'll use in a deployment later. So, how can you easily debug your compiled scripts? There's a .map file that gets built, which tells the browser what your original code looked like.
Chrome and other browsers will automatically load and parse this file when you open your developer tools. Then, you'll be able to see the original source code (and in the original language, for anything transpiled) and debug it as if it were not bundled in the first place.
Don't deploy this map file, unless you want external users to be able to see all your original source code.

Play Framework 2: JavaScript gets duplicated as a result of minification (google closure compiler)

I have a weird issue related to JavaScript minification, the problem is that when placing JavaScript files such as test1.js, test2.js inside /assets/javascript/test folder and using following options for closure compiler:
val defaultOptions = new CompilerOptions()
defaultOptions.closurePass = true
defaultOptions.setProcessCommonJSModules(false)
defaultOptions.setPrettyPrint(true)
CompilationLevel.WHITESPACE_ONLY.setOptionsForCompilationLevel(defaultOptions)
They get minified, but this will cause both test1.min.js and test2.min.js files to share same codes as minified... this will cause some additional JavaScript bugs when files are used within same pages and takes up more disk space.
However, if CompilerOptions is not set, JavaScript compiles properly without duplication but the compilation level is too strict and our JavaScript stops working because it says errors about some things written in those files. Overall, minification process is activated too late to fix all project js files to go through with default compiler options so only option now is to configure it to work in a way which use light minification but without js duplication.. any help on this issue will be highly appreciated!
I'm using Play Framework 2.1.1 with Java project.
It seems that this topic has generated some interests, I wan't to point out that I couldn't reproduce this problem after upgrading to play version 2.2.2. So I will be accepting this as a solution because it seems less hacky way to fix it.
Upgrade the Play Framework to 2.2.2

Bind JavaScript scripts to their respective web pages

I'm working on a large web application which has about 10K lines of JavaScript code (without taking into account the third-party libraries). In order to speed up page loading it has been decided to automatically concatenate every script file into a large script that gets loaded (and cached) on the client the first time the application is accessed. This poses a problem due to the fact that each page had its own script which contained all JavaScript required in (essentially) the same function.
Now if an error occurs in one of the scripts it is really hard to tell where that error came from, since everything is rolled into the same script which is added to each page, as opposed to using explicit script declarations in each page as was done before.
Is there a JavaScript pattern for solving this issue? I'm thinking of something similar to the AngularJS modules that can be bound to certain containers inside a web application's pages.
However, I would like a simple, custom, solution, as we're short on time and we don't have time to implement a framework in our application. It should apply certain scripts (modules) only to their respective pages and it should allow developers to explicitly declare any other scripts (modules) that certain scripts rely on.
Also, implementing an exception handling system to notify users (in the Firebug console, for example) from which module an exception originated (if the page's module relies on other modules) would be great.
Is there a common means of solving such issues in JavaScript (without relying on frameworks)?
A possible solution to your problem could be the use of js source maps. Many concat/minify/uglify tools directly support this feature, while most modern browsers are capable of interpreting them.
You would still serve a single JS file containing all your code (even if this is most likely not the best idea to handle such large amounts of code - largely depending on your overall architecture)
But your browsers developer tools are now able to show you the original file name and line number of an error/console output/etc.
You might most probably not serve the source map file in production.
A good point to get into js source maps is this wiki.

When NOT to use MVC Bundling?

I came across a strange issue in my recent project.
I was using Trent Richardson's Timepicker control to avail time picker functionality in my MVC 4 application. I had relevant JQuery file bundled using MVC bundling feature. I found this working quite well in development environment (Visual Studio 2012).
But when I deployed the website on IIS, I started facing a strange issue, and there was a javascript error "function expected" in that particular bundle. I could see the bundle got loaded because developer tool was showing javascript code when that bundle was selected in "scripts" tab.
Finally, when I referenced the JQuery file directly instead of bundle, it started working fine on IIS. Though the problem got solved, I am now curious to know what was wrong with that particular file if bundled, and if MVC bundling was actually an issue, then why it was working well in development environment, but not in IIS?
Any lights on this much appreciated.
Minification is a complex process by making scripts/styles smaller using techniques such variable name shortening, white space elimination, comments removal, etc... It uses ASP.NET Web Optimization that depends on WebGrease for minification. Of course, there can have issues but I personnaly never noticed that.
Here are some situations, where you should not use bundling
There is only one file in your bundle. Why bundling ?
You are using only famous frameworks such as JQuery or jQuery UI. Do not redistribute scripts that are already served by someone else. Google/Microsoft/Amazon/... already provide CDN for the most popular, open-source JavaScript libraries.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
Your bundle takes only a few Bytes. Web performance Optimization suggests to limit the number of web requests. Everything has a cost. Not very optimal, but sometimes it's better to put inline scripts in your page.
In some architectures. Bundles requests contains a unique identifier used for caching. If any file in the bundle changes, the ASP.NET optimization framework will generate a new token, guaranteeing that browser requests for the bundle will get the latest bundle. When working with some architectures, JS updates can be frequent and will invalidate all your bundles.
On Dev Environment. It's is really really painful to debug a bundle.
Along with Cybermaxs' reply, I have also received following response while posted on ASP.NET Forum In case, if that helps the visitors.
What bundling suppose to do is to put together the script/stylesheet files in a single bundle into a single request and send it to the client so that the browser has to make less calls to get those required script files.
In a development environment, when you do debugging in visual studio. It doesn't do the above process unless you specify it to do so. But in a production environment, when the debug is set to false in the web.config file. it will start to do the above process.
There can be some other reasons as well. such as the script might have two versions. one for debugging and one for production. I came across such a situation with knockout. in my development enviornment I had referenced the debug version of the script. But when I put it into the production enviornment, everything came to a hault. There was a release version for the knockout script file and I had to reference that to make everything work again.

Combined JS File Using YUICompressor Causing Errors

I'm combining multiple js files using YUI Compressor. The command works successfully and outputs a combined file properly.
When I point my page to it, however, it doesn't seem to be read properly and I get this error in the Javascript error console.
YAHOO is not defined
I've tried using the --nomunge and --preserve-semi options but still get the same error.
Any ideas?
are you sure you're including the yahoo YUI js file before your script?
the variable YAHOO is defined within yui.js, so that script needs to exist and be loaded before you attempt to run any javascript that uses it.
Dave,
Hard to know what the problem is without a link to the compressed file.
You may also want to post those links to the dedicated YUI Compressor discussion forum on YUILibrary.com:
http://yuilibrary.com/forum/viewforum.php?f=94
Compressor's developers are there, as well as an interested community of fellow implementers.
-Eric
Did you try to jslint your code?
It may help you detect JS errors
It can usually be integrated in your IDE(I use Textmate), and warn you when you save your js file.
A poor man option is to use the online one at: http://www.jslint.com
Another option is to use a softer compression tool like jsmin to debug the problem. One is hosted here
You compress your files. Run your app, and usually your JS debugger will show you the problem.

Categories