{
"path": "/posts/using-webpacks-defineplugin-with-typescript",
"site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
"tags": [
"webpack",
"typescript"
],
"$type": "site.standard.document",
"title": "Understanding webpack's DefinePlugin (and using with TypeScript)",
"description": "webpack's DefinePlugin allows you to create global constants which can be configured at compile time; here's how to use it with TypeScript",
"publishedAt": "2016-07-23T00:00:00.000Z",
"textContent": "I've been searching for a way to describe what the DefinePlugin actually does. The docs say:\n\n> Define free variables. Useful for having development builds with debug logging or adding global constants.\n\n\n\nI think I would describe it like this: the DefinePlugin allows you to create global constants which can be _configured at compile time_. I find this very useful for allowing different behaviour between development builds and release builds. This post will demonstrate usage of this approach, talk about what's actually happening and how to get this working nicely with TypeScript.\n\nWhat Globals?\n\nFor our example we want to define 2 global constants; a string called __VERSION__ and a boolean called __IN_DEBUG__. The names are deliberately wacky to draw attention to the fact that these are not your everyday, common-or-garden variables. Them's \"special\". These constants will be initialised with different values depending on whether we are in a debug build or a production build. Usage of these constants in our code might look like this:\n\nSo, if __IN_DEBUG__ is set to true this code would log out to the console the version of the app.\n\nConfiguring our Globals\n\nTo introduce these constants to webpack we're going to add this to our webpack configuration:\n\nWhat's going on here? Well, each key of the object literal above represents one of our global constants. When you look at the value, just imagine each outer JSON.stringify( ... ) is not there. It's just noise. Imagine instead that you're seeing this:\n\nA little clearer, right? __IN_DEBUG__ is given the boolean value false and __VERSION__ is given the string value of 1.0.0. plus the ticks off of Date.now(). What's happening here is well explained in Pete Hunt's excellent webpack howto: \"definePlugin takes raw strings and inserts them\". JSON.stringify facilitates this; it produces a string representation of a value that can be inlined into code. When the inlining takes place the actual output would be something like this:\n\nAnd if you've got some UglifyJS or similar in the mix then, in the example above, this would actually strip out the statement above entirely since it's clearly a NOOP. Yay the dead code removal! If __IN_DEBUG__ was false then (perhaps obviously) this statement would be left in place as it wouldn't be dead code.\n\nTypeScript and Define\n\nThe final piece of the puzzle is making TypeScript happy. It doesn't know anything about our global constants. So we need to tell it:\n\nAnd that's it. Compile time constants are a go!",
"canonicalUrl": "https://johnnyreilly.com/posts/using-webpacks-defineplugin-with-typescript"
}