Pages

Saturday, June 7, 2014

Chained JavaScript Inheritance.

Chained JavaScript Inheritance. Thought this may be useful.

Define Objects:

var Fn1 = function () {
    this.a = "a";
};
var Fn2 = function () {
    this.b = "b";
}
var Fn3 = function () {
    this.c = "c";
}

Inheritance

inherit(Fn3).from(Fn2).from(Fn1).provide();

Extend

Fn1.prototype.aa = function () {
    return "AA";
};
Fn2.prototype.bb = function () {
    return "BB";
};
Fn3.prototype.cc = function () {
    return "CC";
};

Instantiate

var ff = new Fn3();

Inherit Object

var inherit = function (subClass) {
    return new function () {
        var superClasses = [subClass],
            result;

        this.from = function (superClass) {
            superClasses.push(superClass);
            return this;
        };

        this.provide = function () {
            for (var i = superClasses.length - 1; i > 0; i -= 1) {
                superClasses[i-1].prototype = new superClasses[i]();
                superClasses[i-1].prototype.constructor = superClasses[i-1];
            }
            return subClass;
        };

        return this;
    };
};

This post is for the purpose of my notes only and sometimes a rant.
“I invented nothing new. I simply assembled the discoveries of other men behind whom were centuries of work. Had I worked fifty or ten or even five years before, I would have failed. So it is with every new thing. Progress happens when all the factors that make for it are ready and then it is inevitable. To teach that a comparatively few men are responsible for the greatest forward steps of mankind is the worst sort of nonsense.”
Henry Ford

Monday, June 2, 2014

AngularJS and MVC 4 Bundling Optimization

When bundling AngularJS controllers, MVC 4 optimization best optimizes by renaming variables. Shrinking of variables reduces file size, however, when incorporating AngularJS and creating a controller, the $scope variable can NOT be renamed.

Not a big fan of third party scripts, yet the company that I was employed with, I had to find a work around.

This is why I enjoy .Net MVC, because I’m not stuck with a deterministic framework. MS MVC offers many tools. Below is how I got Angular to be minified.
Create a new C# class (NoRenameTransform.cs) and extended the IBundleTransform interface.

Include these namespaces:
System.Web.Optimization
Microsoft.Ajax.Utilities


using System;
using Microsoft.Ajax.Utilities;
using System.Web;
using System.Web.Optimization;

And implement the IBundleTransform interface

public class NoRenameTransform : IBundleTransform
{
    protected static Minifier compiler = new Minifier();

    public void Process(BundleContext context, BundleResponse response)
    {
        var codeSettings = new CodeSettings
        {
            NoAutoRenameList = "$scope"
        };
        response.Content = compiler.MinifyJavaScript(response.Content, codeSettings);
    }
}

The Micorsoft.Ajax.Utilities exposes the Minifier / Minifer ASP.NET object, which has a MinifyJavascript method. MinifyJavaScript method optimizes the file’s contents.

Micorsoft.Ajax.Utilities also exposes the CodeSettings object.

Create a field instantiating Minifier object.

Within the Process method, create a variable instantiating CodeSettings object. Set the NoAutoRenameList property to an array of strings of the item(s) that shouldn’t be changed. The $scope variable will not be minified.

var codeSettings = new CodeSettings
{
    NoAutoRenameList = "$scope"
};

IBundleTransform contract expects a Process method, and the Process method arguments expose BundleContext and BundleResponse.

Within the registered bundle configuration file, instantiate a new ScriptBundle class. ScriptBundle inherits from the Bundle class.

ScriptBundle exposes a Generic IList Transforms property.

Clear Transform

Add a new reference to the NoRenameTransform class.

var scriptBundleCore = new ScriptBundle"~/bundles/Modules/EventsApp");
scriptBundleCore.Include("~/Scripts/Modules/EventsApp/app.js");
scriptBundleCore.IncludeDirectory("~/Scripts/Modules/EventsApp/controllers", "*.js", true);
scriptBundleCore.Transforms.Clear();
scriptBundleCore.Transforms.Add(new NoRenameTransform());
bundles.Add(scriptBundleCore);


Bundle lifecycle:
Global.asax, Application_Start, Bundles are registered

BundlesConfig.RegisterBundles(BundleTable.Bundles);

BundlesConfig.RegisterBundles is called and ScriptBundle objects are added to the BundleTable.
ScriptBundles exposes a default transform property, which can be cleared.

scriptBundleCore.Transforms.Clear();

Add new behavior with how the bundle should be minified.

scriptBundleCore.Transforms.Add(new NoRenameTransform());
The transform Process method is called from when the razor view is rendered.

@Scripts.Render("~/bundles/Modules/EventsApp")

Complete Code

Razor View

@{
    ViewBag.Title = "Index";
}

<div ng-app class="container">
    <div ng-controller="EventController">
        {{name}}
    </div>
</div>

@section scripts {
    @Scripts.Render("~/bundles/Modules/EventsApp")
}

Config.asax

using FileUpload_MVC.App_Start;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace FileUpload_MVC
{
 
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundlesConfig.RegisterBundles(BundleTable.Bundles);

        }
    }
}

BundleConfig.cs

using FileUpload_MVC.Models;
using System.Web.Optimization;

namespace FileUpload_MVC.App_Start
{
    public class BundlesConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Clear();
            BundleTable.EnableOptimizations = true;

            var scriptBundleCore = new ScriptBundle("~/bundles/Modules/EventsApp");
            scriptBundleCore.Include("~/Scripts/Modules/EventsApp/app.js");
            scriptBundleCore.IncludeDirectory("~/Scripts/Modules/EventsApp/controllers", "*.js", true);


            scriptBundleCore.Transforms.Clear();
            scriptBundleCore.Transforms.Add(new NoRenameTransform());
            
            
            bundles.Add(scriptBundleCore);
            
        }
    }
}

NoRenameTransform.cs

using System;
using Microsoft.Ajax.Utilities;
using System.Web;
using System.Web.Optimization;

namespace FileUpload_MVC.Models
{
    public class NoRenameTransform : IBundleTransform
    {
        protected static Minifier compiler =  new Minifier();

        public void Process(BundleContext context, BundleResponse response)
        {
            context.UseServerCache = false;
            response.Cacheability = HttpCacheability.NoCache;

            var codeSettings = new CodeSettings
            {
                NoAutoRenameList = "$scope"
            };
            response.Content = compiler.MinifyJavaScript(response.Content, codeSettings);
        }
    }
}

This post is for the purpose of my notes only and sometimes a rant.
“I invented nothing new. I simply assembled the discoveries of other men behind whom were centuries of work. Had I worked fifty or ten or even five years before, I would have failed. So it is with every new thing. Progress happens when all the factors that make for it are ready and then it is inevitable. To teach that a comparatively few men are responsible for the greatest forward steps of mankind is the worst sort of nonsense.”
Henry Ford