次の方法で共有


Enhance your JavaScript debugging life using IE11, Chrome, Opera & Firefox source map support

As a JavaScript developer, I’m sure you’ve already been falling into this scenario. Something goes wrong with the production version of your code. Debugging it directly from the production server is a nightmare. Simply because it has been minified or has been compiled from another language such as TypeScript or CoffeeScript.

Latest versions of the browsers could help you solving this problem by using source map.

According to the great Introduction to JavaScript Source Maps article, source map is “a way to map a combined/minified file back to an unbuilt state. When you build for production, along with minifying and combining your JavaScript files, you generate a source map which holds information about your original files”.

Please don’t hesitate to read Ryan Seddon’s article first as it goes in great details on how source map works. You’ll then learn that source map uses an intermediate file that does the matching between the production version of your code and its original development state. The format of this file is being described here: Source Map Revision 3 Proposal

In this tutorial, I’m going to share the way we’re currently working while developing our WebGL Babylon.js open-source framework: https://www.babylonjs.com. It’s written in TypeScript. But the principles will remain the same if you’re using plain JavaScript compressed/minified or other languages such as CoffeeScript.

Let’s now play with the source map magic directly in the browsers.

The demo page we’re going to use

Recently, I’ve been implementing the support of the Gamepad API in our gaming engine. Let’s use its code for this tutorial.

In this article, I’m going to use up-to-date browsers:

- Internet Explorer 11, August update (version 11.0.9600.17239) or even better, the developer channel version: https://devchannel.modern.ie/ supporting the Gamepad API
- Chrome 38 developer channel (version 38.0.2125.8 dev-m) / Opera 23
- Firefox 31 or Firefox 34 Nightly

Navigate to this URL: https://david.blob.core.windows.net/babylonjs/gamepad/index.html and you’ll obtain this page:

image

Plug an Xbox 360 or Xbox One controller in the USB port of your machine. Press the A button to activate the gamepad and play with it:

image

But don’t worry, you won’t need a gamepad controller to follow this tutorial.

Note: The TypeScript compiler is automatically generating the source map for you. If you’d like to generate a source map while generating your minified version of your code, I would recommend using Uglify JS 2: https://github.com/mishoo/UglifyJS2

For this article, I even mixed both. I’ve minified the JS generated by TypeScript and kept the source mapping intact using this command line:

uglifyjs testgamepad.js -o testgamepad.min.js --source-map testgamepad.min.js.map --in-source-map testgamepad.js.map

How to debug with the original source code

Using Internet Explorer 11

Once the gamepad test page has loaded, press F12 in IE11.

You’ll see that the HTML source is referencing 2 JavaScript files: “babylon.gamepads.js” at the beginning of the page & “testgamepad.min.js” at the very end. The first file is coming from our framework on Github and the second one a simple sample showing how to consume it.

Press on the “Debugger” button (or CTRL+3), then press on the folder icon.

You’ll see that IE11 offers 2 files to debug: “babylon.gamepads.ts” & “testgamepad.min.js”.

image

Let’s start by reviewing the “babylon.gamepads.ts” case. Why does IE show it instead of the .js version being executed by the browser?

This is thanks to the source map mechanism. At the end of the “babylon.gamepads.js” file, you can find this specific line:

 //# sourceMappingURL=babylon.gamepads.js.map

Open “babylon.gamepads.js.map” to understand how it works:

 { "version": 3,
    "file": "babylon.gamepads.js",
    "sourceRoot": "",
    "sources": [ "babylon.gamepads.ts" ], 
    "names": [ "BABYLON", "BABYLON.Gamepads", ... ] }

By reading this JSON file, IE11 knows it should map “babylon.gamepads.ts” to “babylon.gamepads.js”. That’s why, it directly offers you to debug the TypeScript source instead of the compiled JS version.

Open “babylon.gamepad.ts” in the IE11 F12 console and you’ll see something you maybe never seen before, some TypeScript language:

image

You can debug it as you’re used to debug your JS code. Even if it’s the compiled JavaScript version currently being executed by the browser.

Set a breakpoint on the line 17 and press F5 in the browser window. You’ll be able to debug the TypeScript version of the constructor:

image

Step up to line 20, mouse over “this” and expand it to check that “gamepadEventSupported” is set to true:

image

Using Chrome/Opera

Load the same page: https://david.blob.core.windows.net/babylonjs/gamepad/index.html and press F12 in Chrome or CTRL+SHIFT+I in Opera

image

Click on the configuration icon and make sure that the “Enable JavaScript source maps” option is enabled. It should be set by default:

image

Chrome/Opera let you reviewing the executed “babylon.gamepads.js” code but if you tries to set a breakpoint in the JavaScript version, it won’t display it. It will set it instead in the source code mapped to this version: “babylon.gamepads.ts”.

For instance, try to set a breakpoint on the line 18 of the “babylon.gamepads.js” JavaScript file and you’ll see it will be set on the line 17 of the “babylon.gamepads.ts” TypeScript file instead:

image

Of course, you can also set the appropriate breakpoints directly in the TypeScript source as seen with IE11 just before.

Press F5 in the browser window hosting our demo page and you’ll be now able to debug my TypeScript code. Step up to line 20 and mouse over the “this.gamepadEventSupported” variable. It should display true:

image

Using Firefox

Load the same page: https://david.blob.core.windows.net/babylonjs/gamepad/index.html and press CTRL+SHIFT+S to open the native debugger (don’t use F12/Firebug, it doesn’t support source map).

Check that the “Show Original Sources” option is checked:

image

Set a breakpoint as usual on the line 17 and reload the page to break into the code. Firefox doesn’t support mouse hovering on the original source. Step up to line 20 and expand the “this” object instead in the right panel to check that “gamepadEventSupported” is set to true also.

image

What about the minified JavaScript file?

Up to now, we’ve been debugging only the “babylon.gamepads.js” code using the “babylon.gamepads.ts” source. But what about this minified “testgamepad.min.js” JavaScript file?

The first solution is to prettify the code. It works with IE11/Chrome/Opera & Firefox.

In IE11, press the “Pretty print” button or press CTRL+SHIFT+P:

image

In Chrome/Opera, press the “{}” button:

image

In Firefox, press also the “{}” button:

image

This is much better but still not as good as it was with the source map set. To be able to go a step further, we’ve just added a new feature in the August update of IE11. You can load a source map even if you’ve removed it from the .js file.

Imagine you’d like to avoid that anyone could easily debug the production code of your web app using source map but you still want to be able to do so? Just remove the sourceMappingURL line from your .js file.

Using Internet Explorer 11, you can still use the source map by loading your local .map & associated source code. For that, right-click on the “testgamepad.min.js” tab and press “Choose source map”:

image

Download them here: https://david.blob.core.windows.net/babylonjs/gamepad/testgamepad.zip

Unzip that in your preferred directory and navigate to it to choose the right .map file:

image

And now the original source code can be debugged again:

image

Notice that the tab has been renamed to “testgamepad.ts” and that the first variables are now typed as we’re displaying some TypeScript.

Cool, isn’t it? Don’t hesitate to have a look to another cool features we’ve added to F12 recently: Announcing new F12 dev tools features in August update

Feel free to ping me on twitter if you’d like to discuss about this article.

Follow the author @davrous

Comments

  • Anonymous
    August 22, 2014
    Source mapping works well with Haxe too :-)

  • Anonymous
    August 27, 2014
    FWIW, "Add Source map" was added to Chrome a little bit ago, as well. cache.gyazo.com/1b0bc2c4043b78bc5eded1f516f7b07e.png Nice writeup, David!

  • Anonymous
    August 27, 2014
    Thanks Paul for letting me know. I'll update the article asap!

  • Anonymous
    October 05, 2014
    Hi David!! I been reading few of your articles on HTML5 and they are really helpful. I am developing a game for Win/WinPhone 8.1 using Construct2 and as you know it exports the code to HTML5. After compiling the game to my Nokia Lumia device I noticed that there are issues with the way Audio plays on HTML5! The audio stops playing in game or lags with lot of delay.  The same is happening on the 8.1 Phone Emulators. The audio plays perfectly on Windows 8.1. Looks like there is some issue with the Phone version of Internet Explorer. I have tried bringing up this issue to several MS Evangelists, but all my efforts have gone vain! I really hope you could look into this issue and help me and many other WP Developers to built solid games on HTML5. I have created a sample Construct 2 project where you see this issue occurring www.scirra.com/.../viewtopic.php

  • Anonymous
    November 23, 2014
    would love to know how Paul was able to get the 'Add Source Map...' option as shown in the screenshot. thanks!