Thursday, September 17, 2015

TypeScript Private Constants and Minification

I'm currently working on a TypeScript app that has a lot of private static values inside the classes. They don't need to be visible to the outside world, but making a variable "private static" doesn't mean that it will really hide the variable in the compiled JavaScript. It's merely a hint to the compiler to limit access to the insides of the class. Here's an example:

module TestMod {
    export class TestClass {
        private static privateStatic = "I'm private and static";
    }
}

Compiles to:

var TestMod;
(function (TestMod) {
    var TestClass = (function () {
        function TestClass() {
        }
        TestClass.privateStatic = "I'm private and static";
        return TestClass;
    })();
    TestMod.TestClass = TestClass;
})(TestMod || (TestMod = {}));

As you can see privateStatic is completely accessible outside the object after compilation. If you're writing a library that may be used by JavaScript this isn't good (but I probably wouldn't write a JavaScript library in TypeScript). For me the biggest implication of this is that when you minify your JavaScript those members' names can't be modified. The minifier doesn't know that private static variables will never be accessed from the outside.

After running it through a minifier you get this:


var TestMod;!function(t){var a=function(){function t(){}return t.privateStatic="I'm private and static",t}();t.TestClass=a}(TestMod||(TestMod={}));

As you can see privateStatic was not renamed to a shorter name as you might have wanted.

One way we can remedy this is to move the private static variables up into the module. As long as you don't mark them with the export keyword they will be completely hidden from the outside world.


module TestMod {
    var _privateStatic = "I'm private and static";
    export class TestClass {
        public foo() { return _privateStatic; }
    }
}

Compiles to:
var TestMod;
(function (TestMod) {
    var _privateStatic = "I'm private and static";
    var TestClass = (function () {
        function TestClass() {
        }
        TestClass.prototype.foo = function () { return _privateStatic; };
        return TestClass;
    })();
    TestMod.TestClass = TestClass;
})(TestMod || (TestMod = {}));

Now _privateStatic is assigned to a variable in a closure. If we look at the minified JavaScript you can see that _privateStatic has been changed to "n" giving you better minification.

var TestMod;!function(t){var n="I'm private and static",o=function(){function t(){}return t.prototype.foo=function(){return n},t}();t.TestClass=o}(TestMod||(TestMod={}));

One problem with this technique is readability. Notice that I change the name from privateStatic to _privateStatic. I prefix the variable names with an underscore to make it clear that they are defined outside the class but are still private.

If you have a lot of static variables or constants in a class and you're looking to save some bytes in your minified application you might take a look at using this technique. It may make your code a little harder to read but the trade off is you get a smaller app. 

TypeScript Lambda Gotcha

I came across a little gotcha today in TypeScript that I hadn't thought about before (but should have known better). When you use lambdas syntax, if you don't wrap it in curly braces it returns the result of the expression. In most cases this is probably fine, but not if the caller of your function is looking for a return type. I was using the LoDash _.each() function which allows you to pass back false if you want to break the loop. And unfortunately I was setting a boolean variable in the lambda without using curly braces. So every time I set the variable to false it broke the loop and I got bugs :-(.

For example, here I'm not using braces around my lambda expression, so whenever item.condition is not 1 it breaks the loop.

_.each(items, (item) => item.visible = (item.condition === 1));

This compiles down to:

_.each(items, function(item) { return item.visible = (item.condition === 1); });
See how it inserted a return statement? That's not we wanted!

By simply adding curly braces the return is removed and you get the correct behavior.

_.each(items, (item) => { item.visible = (item.condition === 1); });
It compiles to:

_.each(items, function(item) { item.visible = (item.condition === 1); });

So maybe I should start using braces when I don't want to explicitly return a value. But it looks so much cleaner the other way when you just want to do a simple one-liner. So we'll see...

Thursday, December 11, 2014

OWIN and Katana

I've been trying to learn more about OWIN and Katana so let me see if I can break it down here for you.

OWIN is Open Web Interface for .NET. It is a specification for how a web application interact with a web server. It creates an abstraction between web servers and framework components. On top of that it was designed to be simple and have few dependencies on other frameworks. What this allows is for new components to be more easily developed because you don't have a tight coupling to another framework. It also decouples your .Net web sites from IIS so you can run them on other servers/platforms or self host them.

OWIN uses the concept of a pipeline through which requests and responses are passed. OWIN components in the pipeline do something with the request and response and the result is sent back to the user.

Katana on the other hand is Microsoft's implementation of a set of OWIN components.These components include things from servers and hosts to components such as authentication and bindings to frameworks. It is designed to be composed of a number of small focused components that can be added in as needed. This makes your application more efficient because it doesn't have a bunch of things it doesn't need in the pipeline. These components are added via Nuget packages.

You'll often hear the term "middleware" when working with Katana. This is simply one of the logical layers of a Katana application. From bottom to top the layers are Host, Server, Middleware and Application. So as you can see middleware is in the middle between the host/server and your application. This is where the OWIN pipeline components that your application depends on live. These components are specified in your application's startup code. These components can be as simple as a request logger to as complex as the ASP.Net Web API framework.

If you want to get into more details I recommend reading this article.