简体   繁体   中英

Best practice for minifying TypeScript modules

I'm using requirejs and AMD modules for my TypeScript project, with something like 20 different source files at the moment and likely to grow substantially. All of this works, but it's very slow to load all 20 files, so it would be better to have them minified. But because of how requirejs wants to load everything, it seems like it's going to require that I keep the modules in separate files - I don't think I can just take the generated module1.js and module2.js files and minify them into one file and then have requirejs load those without changing some code. (I could be wrong on this.)

The other way that I see to do this is to use the r.js file that requirejs provides to merge all the different files together in a way that still keeps requirejs happy. But r.js requires node.js, and I'd rather not introduce that as a dependency in my build process if there's any other way to do it.

So before I dive into this and try half a dozen different solutions - how are other folks approaching this with big projects?

What you could do is to implement a thin RequireJS shim to use in a minified build. Depending on how much of the RequireJS API you want to use, you could get by with very little. For simplicity you could also use named modules .

Say, while developing you use RequireJS to load your modules. When you want to make a minified build, you could simply include a simple loader in the minified file.

If you have files app.js, foo.js and bar.js as follows:

//from app.js  
define("app", ["foo", "bar"], function(foo, bar) { 
    return {
        run: function() { alert(foo + bar); }
    }
});

//from foo.js
define("foo", [], function() { 
    return "Hello ";
});

//from bar.js
define("bar", [], function() { 
    return "World!";
});

And let's say you minify all those files together. At the top of the file you include the following shim:

//from your-require-shim.js
(function(exports) {

    var modules = {};

    var define  = function(name, dependencies, func) { 
        modules[name] = {
            name:name,
            dependencies:dependencies,
            func:func,
            result:undefined
        };
    };

    var require = function(name) {

        var module = modules[name];

        //if we have cached result -> return
        if(module.result) { return module.result; }

        var deps = [];
        //resolve all dependencies
        for(var i=0,len=module.dependencies.length;i<len;i++) { 
            var depName = module.dependencies[i];
            var dep = modules[depName];
            if(!dep.result) { 
                //resolve dependency
                require(depName);
            }
            deps.push(dep.result);
        }

        module.result = module.func.apply(this, deps );

        return module.result;
    };
    exports.require = require;
    exports.define = define;
}(window));

And execute the module defined in app.js

require("app").run();

Like in this fiddle .

It's a crude PoC of course, but I'm sure you get the meaning.

If you are using ASP.NET MVC 4, you can make a bundle which will minify everything when you deploy to production in a set of files or in a folder. You'll find more info on bundles here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM