menu close mail twitter feed github linkedin share-twitter share-google-plus share-facebook

Alternativas para iniciar um projeto com AngularJS no Visual Studio

Opa, tudo certo?

Hoje vou compartilhar minhas opiniões sobre alguns templates de projetos com AngularJS existentes e que testei para o visual studio.

Estava buscando opções para criar projetos com AngularJS invés de instalar os pacotes via bower, que eu prefiro bastante mas não custa nada dar uma pesquisada e uma chance para outras opções né? :)

Pra quem não trabalha com .NET ou não sabe, a plataforma também conta com uma ferramenta gerenciadora de pacotes, chamada nuget e existem pacotes para muitas dependências de front-end, como jquery, boostrap, angular, entre outros.

Porém eu não gosto de utilizar o nuget para gerenciar dependências do front-end, primeiro porque não é possível customizar o diretório que as dependências serão instaladas, segundo porque o bower é o gerenciador “oficial” de dependências de front-end :D

E outra coisa, pelo que estamos vendo do ASP.NET 5, estão dando foco total para o bower! \o/

Chega de papo e vamos ao que interessa, o que estou utilizando para rodar os projetos:

  • .NET Framework 4.5
  • Visual Studio 2013

Projetos de template testados:

A instalação é muito simples, pelo próprio visual studio em Tools > Extensions and Updates, na aba Online pesquise pelos nomes citados.

Sobre os projetos, vou comentar a estruturação do front-end, sobre o ASP.NET não temos como escapar do problema de alto acoplamento entre responsabilidades, mas no final do post falo um pouco disso!

ASPNET MVC ANGULAR Project Template

Proposta

Project template created for quickly starting up projects which require asp.net mvc 5.0 using angular and web api 2.0

O que eu achei

Além do AngularJS, o projeto está estruturado com bootstrap (CSS), jQuery e jQuery UI.

Notei um cuidado do autor com algumas boas práticas de AngularJS como “ControllerAs”, “vm”.

(function() {
  "use strict";

  angular
    .module("main")
    .controller("AboutController", AboutController);

  AboutController.$inject = ["$scope"];

  function AboutController($scope) {
    /* jshint validthis:true */
    var vm = this;
    vm.title = "AboutController";

  activate();

  function activate() {}
  }
})();

Porém no app.js ele quis utilizar uma variável global para armazenar a referência do main module, o que eu já não gosto.

Também tem uma configuração inicial das rotas de exemplo e um RootController que é utilizado para autorizar o acesso do usuário à rota solicitada.

Segue abaixo o código do app.js completo:

// Main configuration file. Sets up AngularJS module and routes and any other config objects

var appRoot = angular.module("main", ["ngRoute", "ngGrid", "ngResource"]); //Define the main module

appRoot
  .config([
    "$routeProvider", function($routeProvider) {
    //Setup routes to load partial templates from server. TemplateUrl is the location for the server view (Razor .cshtml view)
    $routeProvider
      .when("/home", { templateUrl: "/home/main", controller: "MainController" })
      .when("/contact", { templateUrl: "/home/contact", controller: "ContactController" })
      .when("/about", { templateUrl: "/home/about", controller: "AboutController" })
      .when("/demo", { templateUrl: "/home/demo", controller: "DemoController" })
      .when("/angular", { templateUrl: "/home/angular" })
      .otherwise({ redirectTo: "/home" });
    }
  ])
  .controller("RootController", [
    "$scope", "$route", "$routeParams", "$location", function($scope, $route, $routeParams, $location) {
      $scope.$on("$routeChangeSuccess", function(e, current, previous) {

        var isAuthorized = true; // hard coded - use service to authorize

        if (current.controller != undefined) {
          // -- check here if we are authorized to proceed
          if (!isAuthorized) {
            $location.url("/home");
          } else {
            $scope.activeViewPath = $location.path();
          }
        }
      });
    }
  ]);

AngularJS SPA Template

Proposta

This project is a skeleton for a simple single-page web application (SPA)...

This is a port of the official Angular Seed project, but optimized for the Visual Studio development environment.

O que eu achei

Apesar de seguir o seed oficial do Angular, o template está desatualizado e a última atualização foi em 17/09/2014 e já não condiz com a versão atual do seed.

Mesmo assim o projeto tem specs de jasmine, o que é interessante para quem está começando e querendo aprender sobre testes em javascript.

Além do AngularJS, o projeto está estruturado com bootstrap (LESS) e jQuery.

Assim como o seed oficial o javascript do template não segue boas práticas e ainda compila todos os códigos de controllers, directives, filters e services em um único arquivo, como o exemplo a seguir:

'use strict';

// Google Analytics Collection APIs Reference:
// https://developers.google.com/analytics/devguides/collection/analyticsjs/

angular.module('app.controllers', [])

  // Path: /
  .controller('HomeCtrl', ['$scope', '$location', '$window', function ($scope, $location, $window) {
    $scope.$root.title = 'AngularJS SPA Template for Visual Studio';
    $scope.$on('$viewContentLoaded', function () {
      $window.ga('send', 'pageview', { 'page': $location.path(), 'title': $scope.$root.title });
    });
  }])

  // Path: /about
  .controller('AboutCtrl', ['$scope', '$location', '$window', function ($scope, $location, $window) {
    $scope.$root.title = 'AngularJS SPA | About';
    $scope.$on('$viewContentLoaded', function () {
      $window.ga('send', 'pageview', { 'page': $location.path(), 'title': $scope.$root.title });
    });
  }])

  // Path: /login
  .controller('LoginCtrl', ['$scope', '$location', '$window', function ($scope, $location, $window) {
    $scope.$root.title = 'AngularJS SPA | Sign In';
    // TODO: Authorize a user
    $scope.login = function () {
      $location.path('/');
      return false;
    };
    $scope.$on('$viewContentLoaded', function () {
      $window.ga('send', 'pageview', { 'page': $location.path(), 'title': $scope.$root.title });
    });
  }])

  // Path: /error/404
  .controller('Error404Ctrl', ['$scope', '$location', '$window', function ($scope, $location, $window) {
    $scope.$root.title = 'Error 404: Page Not Found';
    $scope.$on('$viewContentLoaded', function () {
      $window.ga('send', 'pageview', { 'page': $location.path(), 'title': $scope.$root.title });
    });
  }]);

Se você está pensando em fazer um projeto importante recomendo que refatore esses arquivos para ter uma manutenção e testabilidade melhor.

Falando em testabilidade, o autor diz na página do template que para rodar os testes podemos utilizar uma extensão chamada Chutzpah JavaScript Test Runner, mas seria melhor ter um grunt/gulp para rodar o karma, porém não vem como configuração padrão e é necessário criar os arquivos de configuração para tal.

ng.Net.Template

Proposta

The goal of this template is to create a project which supports .NET Web Api, AngularJS, Authentication, Authorization, and simple CRUD operations against web services.

O que eu achei

Além do Angular, o projeto está estruturado com bootstrap (CSS), jQuery, modernizr e respond.

Apesar de não seguir boas práticas, os controllers estão cada um em seu arquivo.

angular.module('home', [])
  .controller('homeCtrl',['$scope','$http', function ($scope, $http) {
    $scope.alert = function () {
      alert("WOW");
    }
}]);

Porém na layout page o bundle está todo separado, carregando mais scripts do que o necessário, não entendi porque o autor deixou dessa forma.

@Scripts.Render("~/ng")
@Scripts.Render("~/app")
@Scripts.Render("~/jquery")
@Scripts.Render("~/bootstrap")
@Scripts.Render("~/misc")

Conclusão

Se você criou algum projeto com algum destes templates deu pra perceber o quão fácil é iniciar um projeto com AngularJS no visual studio, porém, se você está com a intenção de criar um app robusto, testável e bem organizado, eu recomendo uma refatoração encima dessas estruturas.

Algumas dicas:

  1. Isole o projeto de front-end (AngularJS) do projeto de API que você irá consumir
  2. No projeto de API, não deixe todas as dependências do ASP.NET MVC, Web API, autenticação, banco de dados, crie camadas responsáveis por cada função e utilize injeção de dependência
  3. Organize os diretórios do front-end e utilize boas práticas de código e performance com AngularJS
  4. Crie bundles do ASP.NET MVC para facilitar a minificação e compressão dos arquivos
  5. Mas você também pode utilizar grunt/gulp, utilize o que for melhor para o seu caso
  6. Crie o máximo de testes que conseguir para garantir as suas regras de negócio e funcionamento do front-end

Agora, se você criou um projeto com a ideia de servir como prova de conceito, projeto de estudo, projeto de pequeno porte, o uso destes templates vai muito bem e é tranquilo de criar suas funcionalidades e customizações.

Caso tenha alguma dúvida, crítica, sugestão, deixe seu comentário que eu respondo sempre que possível!

Até mais!