9 ms·
What is a Source Map
- sillysaurus3 9y agoA source map is the ability to say, for every character in a minified JS file, "Which source file did this character from? Which line and column?" Note that there are a few types of source maps that vary in quality, so sometimes you don't get accurate column info. http://webcache.googleusercontent.com/search?q=cache:qYxqOqD-x3oJ:cheng.logdown.com/posts/2016/03/25/679045+&cd=1&hl=en&ct=clnk&gl=us http://webcache.googleusercontent.com/search?q=cache:qYxqOqD... The cool thing is, it's really easy to throw together a toy language with first-class debugging and tooling, thanks to sourcemaps. See coffeescript and lightscript for two ecosystems to emulate. https://github.com/jashkenas/coffeescript/blob/master/src/sourcemap.litcoffee https://github.com/jashkenas/coffeescript/blob/master/src/so... http://www.lightscript.org/ http://www.lightscript.org/
- deleted 9y ago[deleted]
- sametmax 9y agoA source map is the reason your browser is so slow after you succeeded to debug your 4Mo webpack generated dev bunddle you spent 3 hours to configure right. And "your browser" is not plural because one config won't work with another browser.
- GuiA 9y agoVery naive question as someone who last wrote production JavaScript in 2008: so basically web developers are reinventing debug symbols?
- ateesdalejr 9y agoNow that you put it that way it sounds funny now.
- acemarke 9y agoPretty much, yeah. Today's web applications go through multiple forms of compilation and transformation. Conversion from ES6 modules to CommonJS, compilation of newer JS syntax into equivalent older syntax supported by more browsers, minification that renames symbols to cut down on the total byte size delivered, and bundling of hundreds of individual modules into a single output JS bundle (or possibly several code-split bundles). Because of that, debugging the delivered source as-is isn't feasible. Sourcemaps allow the browser's devtools to display the original source, and a developer can debug the code as it was before any compilation steps were applied. I saw a post a couple years back that suggested that DWARF debugging symbols could be used as an inspiration for improving sourcemaps: http://fitzgeraldnick.com/2015/06/19/source-maps-are-insufficient.html http://fitzgeraldnick.com/2015/06/19/source-maps-are-insuffi... .
- emh68 9y agoNow I’m wondering when the term “debug symbols” came along and if there was something they called it before that. Google shows no results for “debug symbols” from before 1990, but I have definitely heard of fortran-to-lisp tools and whatnot that are definitely comparable from the 70s.
- gumby 9y agoI first encountered debugging symbols in 1977, so it's an old idea (and I designed objdump, bfd etc to dredge through them).
- abiox 9y agosort of, but not exactly. debuggers in the browser work fine with plain javascript and have the source directly available. js source maps remind me more of stuff like linespecs that you can give to gdb/lldb for mapping.
- the_mitsuhiko 9y agoAnd badly. I rrally wish JavaScript would just use DWARF. Sourcemaps are quite broken, do not contain scope infos and cannot be used to map function names wirhout doing stupid things.
- khuey 9y agoDWARF is kind of a shitshow and it's not really suited for doing this sort of source to source transformation anyways.
- the_mitsuhiko 9y agoI do not see why not. You can compile javascript into a single line and then use the column index as memory address and dwarf should work almost unchanged. Also not sure why DWARF is a shitshow.
- Peaker 9y agoDWARF is terribly designed. It is far more complicated than it needs to be. For example, to map binary locations to line numbers -- it uses its own opcodes and registers in a custom VIRTUAL MACHINE(!!) When it could have had a simple table like: Line Offset 1 0xa 2 0x14 4 0x2a ... Then just compress that with an ordinary compression algorithm rather than inventing silly virtual machines. The debug info itself is encoded in a very cumbersome encoding of debug-information-entries that point to one another. A much simpler method would have been RLP, for example.
- the_mitsuhiko 9y agoThe line number programs of DWARF are pretty well working for the problems they should solve. Out of all things in DWARF that are weird, these are not the issue. We use DWARF at Sentry just fine and I am quite a big of a supporter of the format as ypu can guess. In particular it was designed and specified unlike sourcemaps which are a random google docs page and don’t even solve basic problems such as finding out which function a token belongs to.
- arkh 9y agoThat's kinda sorta the web dev world: reinvent all the wheels! Once they're done a new generation will feel it is too complicated and go back to basics with a new language. And reinvent all those wheels again. This is the magic of software: every decade you can pick low hanging fruits again to improve your resume.
- iamleppert 9y agoAnyone who has worked in real web development knows that source maps are barely functional. When they do work, they are slow and there's a non-trivial delay, during which time the minified source or transpiled source or whatever is shown. There's a 50/50 shot they won't even work at all, and of that 50% of the time they do work, they often don't have the correct line and column. Again, things like the interactive debugger and "pause on caught exceptions" often casually break with source maps. In short, it's a mess.
- foota 9y agoMaybe it wasn't "real web development" but I've worked in projects with O(thousands of lines) of transpiled and minimized typescript where they worked fine.
- jondubois 9y agoI think that the issue is around creating and distributing source maps correctly and also about maintaining the correct configurations to match updates in the source language. I've worked on many projects for large companies and I have to agree with the previous commenter that it feels like source maps often don't work correctly. You can blame the bundling tools, you can blame the deployment process, you can blame the developers... But ultimately, source maps are not so straight forward and they slow things down because they add a lot of unnecessary complexity to the project. I don't think I've ever worked on a CoffeeScript or TypeScript project without encountering at least a few major recurring issues with the source maps. When you have many developers working on the same code, things will break in unexpected ways and so you want to minimize system complexity.
- ehnto 9y agoClosely matching the experience I have with many support tools for development. Including things like docker, vagrant, dependency managers, build pipelines, CI, migration/setup scripts, compilation, codegen... My intuition is that while these all solve real problems, they are complex enough solutions that they themselves have problems over the course of time. Each tool and configuration of the tool individually understood by whoever put it into the project but never understood by all team members. Two things come out of this: when a tool breaks, it can't be fixed by everyone, and because it can't be fixed by everyone no one feels responsible and it stays broken or gets fixed ad hoc by each team member until a real fix is made by someone who can (doesn't always happen). By the time you are a few years into a project your tooling is a mess, people that built it have left, and dependencies and the ecosystem have well and truly moved on. I loved Vagrant, until it broke, on every single project I touched after it was initially implemented and in a myriad weird and wonderful ways. I know these are complex tools, but they often don't feel worth the trouble. They are not robust, they pass out of fashion quickly, and they are rarely effective enough for long enough to truly reap rewards (in my experience). I want these things to work. But they are broken and in the way so often that I prefer not to rely on them. If a builder had to open his magic drill and learn an unfamiliar skillset to fix it every few months he would probably go back to the regular drill that just worked.
- draw_down 9y agoJust debug symbols for JS. Nothing crazy.
- ridiculous_fish 9y agoThe source map format is tricky. One flaw is that the VLQ encoding is strange and hard to get right. 0 may be encoded as either A or B (?). Even the author missed an edge case: -2^31 is wrongly encoded as B (i.e. 0) while the correct encoding 'jgggggE' is wrongly decoded as -1. Try entering them in http://www.murzwin.com/base64vlq.html http://www.murzwin.com/base64vlq.html . More seriously, the format is unsuitable for random access. It must be fully parsed and held in memory to be used.
- deleted 9y ago[deleted]
- jankotek 9y agoThis is why Javascript is 20 years behind...
- jwandborg 9y agoCould you tell me the language which is 20 years ahead of JavaScript?
- nevir 9y agoPretty much all the native ones. When you're debugging c/c++/etc, you're relying on source maps (via dwarf/elf/etc)
- madeofpalk 9y agoI guess for certain definitions of ‘behind’.
- holman 9y agoSomething I’ve been wondering lately and have seen a few different — and rather surprising — takes: do you include source maps in production? I’ve seen a somewhat surprising amount of people say that they absolutely wouldn’t these days, which seems fairly security-through-obscurity. Would love to hear some different opinions on this, though.
- akx 9y agoJust yesterday I used the source maps provided and a short script to "reverse-engineer" a third party's minified Webpack bundle into a tree of original source files, complete with comments...
- optimiz3 9y agoLocks make good neighbors, but they wont stop a thief. You're not obligated to make it easy for someone to reverse-engineer/steal/clone your client code.
- nallerooth 9y agoI wouldn't, or to be more precise - I wouldn't by default. I prefer to enable things like source maps via an environment variable or a special build - when I know that I need to debug something. By always including source maps, I just increase the asset size for the site's visitors, with "no benefit" (most end users won't have a clue about how to debug something). Regarding the security aspect - don't put anything you know to be sensitive/insecure on the Internet in the first place.
- gumby 9y agoHow is this different from debugging info? They should just use DWARF instead of reinventing the wheel.
- johncolanduoni 9y agoHow would you map 90% of the things in DWARF (like stack variable addresses, structure memory layouts, and the honest-to-goodness VM that produces line mappings) to JavaScript? The problems they're solving don't look remotely similar even if you squint.
- colordrops 9y agoDo you also think that no other make-like systems should have been built?
- flukus 9y agoNot all, but most make-like systems are a waste and are basically just "make in $language" that don't do anything new or novel, the just give you a different syntax and set of functions to learn. So yes, I do think we'd be better off having a lingua franca build systems to use for every language rather than dozens of different ones.
- sametmax 9y ago"make in $language" is not a waste if sudendly you can "x install your framework" and get it without additional setup, and crossplateform. It's not a waste if you can leverage what your teams existing knowledge instead of learning the quirks and tricks of make. It's not a waste if you can use your existing tooling (editor plugins, debuggers, unit test frameworks...) to process your build files.
- matejn 9y agoI believe "x install your framework" is the job of a package manager, not a build tool. I don't see how your argument holds ground. If everyone used make, tooling would support it, and you wouldn't need to learn the "quirks and tricks" of a dozen other systems. The problem with make is that it's not portable, since it needs to call system specific binaries, like rm(1) vs del. There's also the BSD vs GNU divide. Other than that, a newfangled tool like gulp doesn't even have a clean one liner for copying one file to a different location with a different name. It's absurd.
- gowthamgts12 9y agoThanks sir.
- Spearchucker 9y agoHe says in his article that minification is best practice. And I imagine I'm a dinosaur and (or) completely out of touch, because I disagree. Minifcation becomes a thing when the page is too big. And many pages* contain bloat that do nothing to improve my lot. I write my CSS by hand, and keep it as sparse as I can. When I do use JavaScript it does a specific thing, like filter a dataset or move a slider. And it's easy to debug because it's pithy, and uses sensible naming. * Some pages - specifically real-time apps - need lots of JS bloat. I get and accept that. Happily I don't need to make any of those beasts.
- Klathmon 9y agoYou are making a mistake thinking this technology is for your use case. Just because you use JavaScript in your websites doesn't mean that you are making a "web app". Your 1kb JS file might not need minification, but my 1.2MB app that minifies down to 200KB does. They are not the same any more than a 6 line python script is the same as Django
- joekrill 9y agoIn pretty much every case minification is going to reduce the payload, which is going to reduce the amount of data a client has to download. Whether you're minifying 1KB down to 100 bytes, or 50 MB down to 3 MB -- you're still benefiting. I can't really see a case where that is a bad thing, particularly when you have source maps to get you back to the original source code, anyway. Your stance just seems very naive.
- Spearchucker 9y agoSource maps have never worked out for me, and my pages are tiny (I see no benefit in sacrificing readability for a reduction from 1K to 100 bytes).
- rimliu 9y agoThat's an interesting claim about readability. You may as well argue that compilation of C program reduces its readability. Minification should be a step of making a production build. It does not affect source code and thus it does not affect readability.
- childintime 9y agoThis reminds me of what I think is the curious omission of source maps inside editors or IDEs. The opportunity is most easily explained by pointing at the issue of significant whitespace: it should not be a language feature, but an editor option. Those that want it should get it, no need to fuss at the language level. It is not semantics. Source maps could do the trick. One could edit a source mapped version, and have the edits piped back to the source. I'm sure there are lots more applications that make sense for an editor. Imagine having to edit a big table with lots of columns. If one could supply the editor with a filter that pairs the text down to the interesting tidbits, with a source map, edits could be mapped back to the source. That would be a big win. Another trivial example are coding styles. Everybody has their own, the editor should interface that style to the code-base. I believe source map support in editors could enable this. The biggest win would be an ecosystem of plugins for such services.
- Dowwie 9y agocheck out the Rust implementation that Armin made for Sentry: https://blog.sentry.io/2016/10/19/fixing-python-performance-with-rust.html https://blog.sentry.io/2016/10/19/fixing-python-performance-...
- Timothycquinn 9y agoFor security and possibly performance purposes, I would like to forego sending source maps to the client in Production and instead store the source maps, using versioning on the server and just send serialized client side stack traces to the server for error reporting. Has anyone done this before? I tried digging into this several times in the past but came up empty.
- untog 9y agoOne immediate issue that comes to mind: source maps aren't downloaded unless the user has the dev console open. Unless you have an answer for how you're going to detect that, any custom solution will be less performant than the existing solution.
- yesimahuman 9y agoYes, this works identically. You would need a sourcemap library like source-map for JS or libsourcemap for python. Instead of having the browser load the sourcemap you just load it in the library and map stack frame line:col for the corresponding file. We have an exception service for for our company that relies on private sourcemaps and this is our approach.
- bretthoerner 9y agoI could be misunderstanding your question, but the Sentry JS SDK sends exceptions to the server and they are unminified on the server side. The server will attempt to download the sourcemaps automatically, but you can also disable them in production and push them to Sentry manually (when you deploy). So this this gives you one existing option, and at least shows it's possible if you need a custom solution.
- paulddraper 9y agoAt Lucid (https://www.lucidchart.com https://www.lucidchart.com), we've used a home-grown solution that stores the versioned source maps in S3, and decodes the stack traces server-side and adds it to the original trace in the logging system. Plus caching the decoding. We've looked at Sentry and might use that. They offer hosted and open-source on-prem solutions.
- ivanhoe 9y agoUnfortunately, at least in my experience, JS source maps are pretty useless for any real life debugging because browser almost never manages to set a breakpoint on the line that you've marked, so it gives you some value only if you don't already have access to the original unminified sources. However CSS source maps are of a great help for less/sass.
- jschorr 9y agoSome interesting history of source maps: They actually are older than the article suggests, having been original developed and used internally at Google starting in early 2009. At the time, Google had some of the largest applications written in JavaScript running inside of the browser, optimized and minified using Closure Compiler [1]. One focus of Closure Compiler was/is minimizing bytes sent over wire, which resulted in trying to debug issues that occurred on Line 1, Character XXXXX of the minified file. As an engineer working 20% on a Gmail feature, I grew incredibly frustrated with having to add `console.log` or `alert` calls everywhere, and so threw together extensions to both Closure Compiler and Firebug to produce the very first iteration of source maps. While only used by a few members of the Gmail and apps teams at first, the source maps and “LavaBug” (our extension to Firebug to consume source maps) spread internally, so much so that we decided to release them as part of Closure Compiler’s first release (“LavaBug” being released as “Closure Inspector”) [2]. The reason the spec lives in a Google Doc is that it is not a standard; it is a specification that we wrote at Google and saw teams both internally and externally pick up as it gained steam, eventually being supported in all major browsers and most compile-to-JavaScript tools; shows how having a solution to a problem can cause it to grow into a “standard”. Source: I invented Source Maps [1] https://github.com/google/closure-compiler https://github.com/google/closure-compiler [2] https://googlecode.blogspot.com/2009/11/introducing-closure-tools.html https://googlecode.blogspot.com/2009/11/introducing-closure-...
- itwy 9y agoI choose to believe the article writer.
- ricardobeat 9y agoIf you click the fist link in the article, going to the google doc, you'll find this: The original source map format (v1) was created by Joseph Schorr for use by Closure Inspector Username checks out. Snark or not, please avoid posting this type of comment here.
- itwy 9y ago
- paulirish 9y agoSokra (of webpack) and I have hacked on a sourcemap visualizer which really illuminates exactly how the mappings work: https://paulirish.github.io/source-map-visualization/#raven https://paulirish.github.io/source-map-visualization/#raven A few examples are available, but you can also drag in your own files to view those.
- davidcamel 9y agoWhen I look at downloaded minified JS files in my browser's dev tools, there's a button to de-minify/pretty-print the JS. What is the advantage of the source map?