How to Fix Your Server-Side TypeScript Call Stack With webpack.BannerPlugin

TypeScript Webpack

TypeScript is a great language choice when you're writing a large server-side Node.js project such as a universal React+Redux web application. However, debugging errors is challenging if you're not set up for it properly.

Take an error call stack, for example...

An Insane Call Stack

This is what TypeScript server-side errors can look like (without source map support):

Error: Big scary error message
        at Object.defineProperty.value (D:\BitBucket\Project\dist\server.js:2:8875)
        at t (D:\BitBucket\Project\dist\server.js:1:163)
        at Object.defineProperty.value (D:\BitBucket\Project\dist\server.js:22:2851)
        at t (D:\BitBucket\Project\dist\server.js:1:163)
        at Object.e.exports (D:\BitBucket\Project\dist\server.js:30:27387)
        at t (D:\BitBucket\Project\dist\server.js:1:163)
        at Object.anonymous (D:\BitBucket\Project\dist\server.js:21:29025)
        at t (D:\BitBucket\Project\dist\server.js:1:163)
    

Oh, I have an error on line 2... at column 8875 of a minified JavaScript bundle.

frustrated

Thanks, log file.

A Sane Call Stack

Once you have source map support enabled, the stack traces show you real line and column numbers from your actual source files. It's almost like being back in C#. Almost.

This is what TypeScript server-side errors look like with source map support enabled:

Error: Big scary error message
        at Object.defineProperty.value (...\src\app\reducers\sessionReducer.ts:9:37)
        at __webpack_require__ (...\webpack\bootstrap af0efb5a57f02f296438:19:1)
        at Object.defineProperty.value (...\src\app\reducers\appReducer.ts:4:26)
        at __webpack_require__ (...\webpack\bootstrap af0efb5a57f02f296438:19:1)
        at Object.module.exports (...\src\server\webRequestHandler.ts:5:22)
        at __webpack_require__ (...\webpack\bootstrap af0efb5a57f02f296438:19:1)
        at Object. (...\src\server\webServer.ts:8:29)
        at __webpack_require__ (...\webpack\bootstrap af0efb5a57f02f296438:19:1)
    

Oh, okay. Hello… error on line 9 of sessionReducer.ts.

FIXED

How do we do it? Simple, with webpack.BannerPlugin.

Webpack includes a plugin called BannerPlugin that allows you to insert content at the beginning of a bundle. I think it's intended for things like copyright and license statements (you'd never know, though, because the documentation is... sparse).

Fortunately, we can also use it to inject a require statement to setup source map support.

First, add the source-map-support package to your project

npm install --save source-map-support

Then update the webpack configuration for your server bundle to include the BannerPlugin as follows:

Webpack v1.x

module.exports = {  devtool: 'source-map',  plugins: [    new webpack.BannerPlugin(      'require("source-map-support").install();',      { raw: true, entryOnly: false }    ),  ],};

Webpack v2.x

(BannerPlugin had a breaking change from v1 to v2)

module.exports = {  devtool: 'source-map',  plugins: [    new webpack.BannerPlugin({      banner: 'require("source-map-support").install();',      raw: true,      entryOnly: false    }),  ],};

Good luck with your debugging!

What other TypeScript tips and tricks is your project missing?

Stay in the loop by signing up on my email list where I write about TypeScript and related web development topics.