2
votes

I'm working on a large typescript project. I prefer to create many small classes and put each in a separate file, and use deeply nested namespaces ('internal modules' in typescript). I consider this to be good practice as it encourages encapsulation, testability, reusability etc. I have more than a hundred small typescript files with deep namespaces.

The compiled .js output for each typescript file contains 3 lines of autogenerated 'boilerplate' for each file, for each level of namespace (2 at the top, one at the bottom). For example, here is a typescript file containing a single empty class, inside 4 levels of namespace:

module a.b.c.d {
    export class MyClass {
        constructor() {
        }
    }
}

This compiles into the following .js:

var a;
(function (a) {
    var b;
    (function (b) {
        var c;
        (function (c) {
            var d;
            (function (d) {
                var MyClass = (function () {
                    function MyClass() {
                    }
                    return MyClass;
                })();
                d.MyClass = MyClass;
            })(d = c.d || (c.d = {}));
        })(c = b.c || (b.c = {}));
    })(b = a.b || (a.b = {}));
})(a || (a = {}));

For performance, I want to merge/minify my .js files into a single file for production. If I simply append the files in the correct order, the boilerplate for getting in and out of the namespace will be repeated for each file. In the case of small .ts files, this will comprise a significant overhead.

My question: is there some way to merge/minify my .js files in a way that strips out the boilerplate for these deep namespaces in cases where sequential .js files share the same namespace?

1
The simplest way to optimize for this problem is to use compression (for example gzip) - this kind of repetition is very well handled. - Fenton
Do you use any kind of build process? Have you tried compiling in a single file? I do this, but actually never checked for redundancy of this overhead code. - Hugues Stefanski
The overhead should not be that huge of an issue since the creation of the namespaces is only ever run once, and everything is set up one time only? If its the file size overhead you are referring to that could be a problem sure, I am not sure there is an easy fix for that. - Nypan

1 Answers

1
votes

I understand that migrating from internal to external modules can be a lot of work but it is your best option for the future.

Once you have created external modules you can compile your TypeScript code into CommonJS or AMDmodules using the --module flag:

tsc myfile.ts --module "amd" 
tsc myfile.ts --module "commonjs" 

Then you can use the require.js optimizer to bundle all the AMD modules in your application into one single optimized file.

If you use commonJS you can use Browserify to bundle all your external modules into one single optimized file. Hope it helps.

I have created a Github project that showcases how to automate this process https://github.com/remojansen/modern-workflow-demo