_header.scss that gets imported into
global.scss which is compiled to
global.css. That final CSS file is what gets loaded in the browser, so for example, when you inspect an element in DevTools, it might tell you that the
display: flex; because it says so on line 387 in
But because that final CSS file is probably minified (all whitespace removed), DevTools is likely to tell us that we’ll find the declaration we’re looking for on line 1! Unfortunate, and not helpful for development.
That’s where source maps come in. Like I said up top, source maps are special files that connect that final output file the browser is actually using with the authored files that you actually work with and write code in on your file system.
Typically, source maps are a configuration option from the preprocessor. Here’s Babel’s options. I believe that with Sass, you don’t even have to pass a flag for it in the command or anything because it produces source maps by default.
So, these source maps are for developers. They are particularly useful for you and your team because they help tremendously for debugging issues as well as day-to-day work. I’m sure I make use of them just about every day. I’d say in general, they are used for local development. You might even
.gitignore them or skip them in a deployment process in order to serve and store fewer assets to production. But there’s been some recent chatter about making sure they go to production as well.
But source maps have long been seen merely as a local development tool. Not something you ship to production, although people have also been doing that, such that live debugging would be easier. That in itself is a great reason to ship source maps. […]
Additional, Rails 6 just committed to shipping source maps by default in production, also thanks to Webpack. You’ll be able to turn that feature off, but I hope you won’t. The web is a better place when we allow others to learn from our work.
Check out that issue thread for more interesting conversation about shipping source maps to production. The benefits boil down to these two things:
- It might help you track down bugs in production more easily
- It helps other people learn from your website more easily
Both are cool. Personally, I’d be opposed to shipping performance-optimized code for learning purposes alone. I wrote about that last year:
I don’t want my source to be human-readable, not for protective reasons, but because I care about web performance more. I want my website to arrive at light speed on a tiny spec of magical network packet dust and blossom into a complete website. Or do whatever computer science deems is the absolute fastest way to send website data between computers. I’m much more worried about the state of web performance than I am about web education. But even if I was very worried about web education, I don’t think it’s the network’s job to deliver teachability.
Shipping source maps to production is a nice middle ground. There’s no hit on performance (source maps don’t get loaded unless you have DevTools open, which is, IMO, irrelevant to a real performance discussion) with the benefit of delivering debugging and learning benefits.
The downsides brought up in recent discussion boil down to:
- Sourcemaps require compilation time
- It allows people to, I dunno, steal your code or something
I don’t care about #2 (sorry), and #1 seems generally negligible for a small or what we think of as the average site, though I’m afraid I can’t speak for mega sites.
One thing I should add though is that source maps can even be generated for CSS-in-JS tooling, so for those that literally inject styles into the DOM for you, those source maps are injected as well. I’ve seen major slowdowns in those situations, so I would say definitely do not ship source maps to production if you can’t split them out of your main bundles. Otherwise, I’d vote strongly that you do.
One solution to this that lets you have your cake and eat it too, is to control access on the .map files, so that they can only be accessed by your company’s intranet or a specific IP, or simply don’t deploy the .map file in production, until you need it (less secure)
Another, would be to have the generated sourcemaps links point to localhost, then “side-serve” the sourcemaps from your own machine. You can do this with webpack
Finally, if you are using chrome, you can deploy files without the sourcemap link to production, then use local overrides to add the links back when you need it.
Honestly, these are all too involved that what I would like. I remember when sourcemaps first came out for Chrome Dev Tools, you could right click a .js file and choose “Load Sourcemaps” which would then open a file dialog to choose your .map file. That’s the easiest thing imho.
Here’s a nice article that goes into further detail on the matter: https://itnext.io/using-sourcemaps-on-production-without-revealing-the-source-code-%EF%B8%8F-d41e78e20c89
This. Also, many modern instrumentation tools have support for private sourcemaps. That means your client-side stack traces, when collected and processed by these tools/services, will tell you a lot of information much more quickly.
I’ve never given a thought to wether or not to ship sourcemaps to production. I enjoy the benefits of them in local development, and they aren’t ignored in git so they always get shipped, and I don’t really see a problem with that.
There’s not really a way someone can steal anything other than some CSS tricks (no pun intended) or JS hackery. You’d still need the back-end code (PHP or otherwise) for anything to actually function.
And on top of that, if some of your users/customers are having issues, it would be easier to diagnose in a real world scenario because you can see the exact JS/CSS that is having the issues on the live server.
Interesting thing to think about nonetheless :)
Yes. You do. Slower build times is fine if it means time to solving a major issue is decreased significantly.
I agree that sourcemap files should be deployed on production. If one is worried about showing their “real code”, Webpack has a feature to host the sourcemap files on an external server. This way you can put them somewhere that requires authorization.
If you have a boss like I had who edits the production code on the live server, you really depend on sourcemaps being everywhere possible.
Print them out for emergency debugging on the go.
I just transfer all sources, unmodfied, via ftp to the production systems, applying some filters to avoid overwriting production settings, therefore no need for a build chaine or sourcemaps.
Source Maps for JS are also important for error tracking, since tools like Sentry can use them to show the original code location from the exception backtrace.
You should always have map files, and especially if you’re working in production. But there is a difference between having map files and having them publicly exposed.
From my experience, it’s best to have them in a separate .map file and then restrict access to that file. My webpack configuration sets any .map files as private when uploading to my AWS S3 bucket. I have to sign into AWS first to then have access to said files from the browser.
I also log client-side JS errors and upload the stacktrace to a reporting server. From there I have a node script that will pull the .map file with proper credentials and tell me the the correct line and file.
Maybe I’m incorrect, but I assumed that source maps were only downloaded if you embed them or view them in the browser’s dev tools. Otherwise, they have no effect on the web page, so there shouldn’t be any performance cost other than the few characters used to reference the .map file.
Considering that we often have to fix bugs that only appear in production, they are an invaluable tool that should always be used regardless of the environment.