Использование TypeScript (на примере angularjs) в Visual Studio 2015

  • Tutorial
Решение этой проблемы заняло у меня несколько часов, поэтому, дабы сэкономить время другим участникам .Net сообщества, решил написать небольшую статью на хабр.

Первым делом, открываем packages.json и добавляем пакеты tsd (TypeScript Definition manager) и grunt-tsd (для взаимодействия с grunt).



Пробуем загрузить пакеты и видим, что пакет tsd почему-то не загружается.


Чтобы понять в чем проблема, попытаемся установить через консоль.
npm install tsd -g
Если раньше не были установлены, устанавливаем git, python (v2.x.x) и nodejs. Все они должны быть прописаны в PATH.

Но это мелочи по сравнению с тем, что должна быть установлена одна из предыдущих версий Visual Studio (подойдет версия express или community), т.к. node-gyp, учавствующий в установке пакета, пока не умеет использовать компилятор VS2015.


После установки предыдущей версии Visual Studio выполним в командной строке:
npm install tsd -g --msvs_version=2013
, где 2013 — версия студии. Если устанавливалась Express версия, нужно указать --msvs_version=2013e.

Если команда выполнилась без ошибок, можем вернуться в студию и попробовать загрузить пакеты снова.
Загрузилось!

В корень проекта добавляем файл tsd.json, в котором указаны какие TypeScript определения из репозитория нам нужно загрузить. Для примера:
{
	"version": "v4",
	"repo": "borisyankov/DefinitelyTyped",
	"ref": "master",
	"path": "ClientSide/typings",
	"bundle": "ClientSide/typings/tsd.d.ts",
   	"installed": {
		"bootstrap/bootstrap.d.ts": {
			"commit": "1c829808b649eb0c794ec8caf38177495a5d7630"
		},
		"jquery/jquery.d.ts": {
			"commit": "1c829808b649eb0c794ec8caf38177495a5d7630"
		},
		"angularjs/angular.d.ts": {
			"commit": "1c829808b649eb0c794ec8caf38177495a5d7630"
		},
		"angularjs/angular-resource.d.ts": {
			"commit": "1c829808b649eb0c794ec8caf38177495a5d7630"
		}
	}
}

В gruntfile.js добавим операции, которые будут выполняться автоматически при сборке проекта. В данном случае, в конфиг, передаваемый в функцию grunt.initConfig, добавлен раздел tsd и в конце файла добавлена регистрация таска grunt-tsd:
module.exports = function (grunt) {
    grunt.initConfig({
        bower: {
            ...
            }
        },
        tsd: {
            refresh: {
                options: {
                    command: 'reinstall',
                    latest: true,
                    config: 'tsd.json',
                    opts: {
                    }
                }
            }
        }
    });

    grunt.registerTask("default", ["bower:install"]);

    grunt.loadNpmTasks("grunt-bower-task");
    grunt.loadNpmTasks("grunt-tsd");
};


Сохраняем. В контекстном меню gruntfile.js выбираем Task Runner Explorer.


Если не появилась секция tsd, нажмите в Task Runner Explorer кнопку Refresh. После этого кликаем правой кнопкой на таске tsd и выбираем Run.

В выводе Task Runner Explorer должна появится надпись «Done, without errors», а в Solution View появится папка Client Side, в которой будут TypeScript файлы. Файл tsd.d.ts содержит ссылки на все установленные пакеты.

Добавим в проект пару файлов (Resharper и студия могут ругаться, считая код не валидным):
  • ClientSide/app.ts
    /// <reference path="typings/tsd.d.ts" />
    module Demo {
        'use strict';
    
        var todomvc = angular.module('app', [])
            .controller('demoCtrl', DemoCtrl);
    }
  • ClientSide/Interfaces/IDemoScope.ts
    /// <reference path="../typings/tsd.d.ts" />
    module Demo {
        export interface IDemoScope extends ng.IScope {
            greeting: string;
            login: (name: string) => void;
        }
    }
  • ClientSide/Controllers/DemoCtrl.ts
    /// <reference path="../typings/tsd.d.ts" />
    /// <reference path="../interfaces/idemoscope.ts" />
    module Demo {
        'use strict';
    
        export class DemoCtrl {
    
            constructor(private $scope: IDemoScope) {
                $scope.greeting = "Wellcome!"
                $scope.login = function (name) {
                    $scope.greeting = "Hello, " + name + "!";
                }
            }
    
        }
    }


Сейчас нам нужно всё это скомпилировать в js файл. Для этого в packages.json добавляем
«typescript»: "^1.4.1",
«grunt-typescript»: "^0.6.1"

Сохраняем. В Dependencies/npm из контекстного меню вызываем Restore Packages.

В gruntfile.cs добавляем этап генерации на основе typescript и регистрацию таска:
module.exports = function (grunt) {
    grunt.initConfig({
        bower: {
            ...
        },
        tsd: {
            ...
        },
        typescript: {
            base: {
                src: ['ClientSide/**/*.ts'],
                dest: 'wwwroot/app.js',
                options: {
                    module: 'amd',
                    target: 'es5'
                }
            }
        }
    });

    ...

    grunt.loadNpmTasks("grunt-typescript");
};


Сохраняем, переходим в Task Runner Explorer, обновляем, запускаем таск typescript. Если все выполнилось успешно, в папке wwwroot будет лежать файл app.js, скомпилированный на основе всех *.ts файлов в папке ClientSide.

Чтобы не запускать генерацию этого файла вручную, можно в Task Runner Explorer на таске typescript вызвать контекстное меню и выбрать Bindings — After Build.

С этого момента при каждом билде, файл app.js будет генерироваться автоматически.

Теперь нам в проекте не хватает самого angularjs.
Добавляем в bower.json:
  • В раздел dependencies
    "angular": "^1.3.10"
  • В раздел exportsOverride
            "angular": {
                "": "*.{js,css}"
            },

Сохраняем. В Task Runner Explorer запускаем таск bower. В папке wwwroot/libs появится папка с angularjs.

Завершающий этап.
В _Layout.cshtml:
  • Добавляем аттрибут для инициализации AngularJS
    <html ng-app="demo">
  • перед @RenderSection(«scripts», required: false) подключаем JS файлы:
    <script src="~/lib/angular/angular.js"></script>
        <script src="~/app.js"></script>

Содержимое Index.cshtml заменяем на:
 <div class="jumbotron" ng-controller="demoCtrl">
    <h1>{{greeting}}</h1>
    <input type="text" ng-model="name" />
    <button ng-click="login(name)">Log In</button>
</div>

F5, запускаем!


Исходники доступны на github.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 15

    +2
    Я наверное блондинка, но нафига всё это? В смысле, в студии же есть свой компилятор Typescript. И ангуляровские приложения на ts с этим компилятором пишутся…
      0
      VS 2015 умеет анализировать TypeScript (подсветка синтаксиса и т.д.), но сама теперь не компилирует.
        +1
        Серьёзно? То есть теперь чтоб в студии разрабатывать на typescript нужно возится с nodejs и больше никак? Может в релизе исправят?
          0
          Может исправят, но честно говоря, всё не так уж сложно. Сейчас больше напрягает тот факт, что ни решарпер, ни студия не в состоянии правильно анализировать код сложных TypeScript определений (таких как angular.d.ts или jquery.d.ts). Приходится разрабатывать, игнорируя сообщения об ошибках.
            +2
            Хм, я использую эти определения(vs2013 + resharper 9.01) и не замечал ничего такого. Можно подробнее?
              0
              VS 2015 жалуется на ошибки в angular.d.ts, хотя компилятор генерирует js файл без ошибок.
              0
              Специально поставил vs2015, typescript работает как раньше. Почему-то пришлось переустановить typescript для vs2013, но никаких grunt`ов и прочего не понадобилось. Так что смысл статьи мне теперь не понятен.
                0
                Вы создали проект под vNext или открыли старый?
                  0
                  Создал новый проект «Html application with TypeScript»
          0
          VS 2015 в стадии preview сейчас? Что за боль с установкой? Половина статьи — страдания и опущения, связанные с установкой и решением проблем там, где это особо и не надо. К слову, совсем недавно скачал ts, установил, поддержка в VS 2013 была отличной, проблем не испытываю. Пользуюсь как здоровый человек.
          Вторая половина — откровенный «hello, world». Пользы минимум, на свете не так много ССЗБ, простите за откровенность.
            0
            Основная боль связана с тем, что «node-gyp, учавствующий в установке пакета, пока не умеет использовать компилятор VS2015». В гитхабе уже есть фикс по этому поводу, но новая версия пакета еще не в релизе.

            В VS2013 с TypeScript было гораздо проще, всё так. Но в VS2015 используются решения, распространненые в OpenSource сообществе. Теперь стало гораздо проще подключать сторонние утилиты для компиляции, кодогенерации, загрузки пакетов и т.п.
            +1
            Не используйте Python 2.7.3 — в нем бажный OpenSSL (пусть здесь это не используется, но если вы его поставите, то потом, скорее всего, будете использовать и для других вещей, для которых нужен питон).

            Текущей версией для ветки 2.7 является 2.7.9.
              +1
              Спасибо, подправил статью.
              0
              Что они сделали с ASP.NET…
                +1
                Что?) Имхо все просто офигенно.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое