TypeScript для ASP.NET MVC 4 веб-приложений

Microsoft выпустил новый язык для разработки веб-приложений – TypeScript. Давайте посмотрим что он из себя представляет и как его можно использовать в ASP.NET MVC веб-приложениях.

Что такое TypeScript?

В первую очередь необходимо отметить, что TypeScript это не самостоятельный язык. Он является развитием знакомого всем JavaScript и предоставляет возможности, которых в нем сильно не хватает:

  • строгая типизация;
  • интерфейсы;
  • модули (аналог namespace в C#);
  • классы в стиле C#;

Все это наглядно демонстрирует следующий код:

// Interface
interface IPoint {
    getDist(): number;
}

// Module
module Shapes {

    // Class
    export class Point implements IPoint {
        // Constructor
        constructor (public x: number, public y: number) { }

        // Instance member
        getDist() { return Math.sqrt(this.x * this.x + this.y * this.y); }

        // Static member
        static origin = new Point(0, 0);
    }

}

// Local variables
var p: IPoint = new Shapes.Point(3, 4);
var dist = p.getDist();

Обратите внимание, что конструктор класса Point типизированный и принимает два числа. Попытка подставить в качестве любого из параметров строковое значение приведет к ошибке (что будет отражено как в редакторе Visual Studio 2012, так и при сборке проекта).

При компиляции код на TypeScript превращается в обычный JavaScript, который и используется на страницах веб-приложения. Таким образом решен вопрос совместимости с существующими браузерами.

Для Visual Studo 2012 доступно дополнение, которое позволяет при редактировании исходного кода использовать такие возможности как:

  • статический анализ кода;
  • символьная навигация;
  • автодополнение имен функций;
  • рефакторинг.

Также существует поддержка для следующих редакторов:  Emacs, Sublime Text и Vim.

На официальном сайте TypeScript расположена интересная "игровая площадка". Она позволяет ввести TypeScript код и посмотреть какой JavaScript будет для него сгенерирован.

Исходный код проекта доступен на CodePlex: http://typescript.codeplex.com/

Добавляем поддержку TypeScript в проект

Для того, чтобы использовать TypeScript в своем веб-проекте необходимо:

1) Установить дополнение для Visual Studio 2012, eсли это еще не было сделано. Оно уже содержит компилятор TypeScript в JavaScript.

2) В файл проекта <ProjectName>.csproj добавить следующий код:

<?xml version="1.0" encoding="utf-8"?>
<Project>
  ... 

  <Target Name="BeforeBuild">
    <Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\TypeScript\0.8.0.0\tsc&quot; @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />
  </Target>

</Project>

Обратите внимание, что номер версии указан в пути до компилятора. Возможно, что при выходе обновлений его придется модифицировать вручную.

3) Теперь можно добавлять в проект ts-файлы, используя пункт меню New Item. Если в нем отсутствуют файл файлы типа TypeScript, то необходимо закрыть Visual Studio и самостоятельно запустить файл TypeScriptLanguageService.vsix из папки $(PROGRAMFILES)\Microsoft SDKs\TypeScript\0.8.0.0\ для установки расширения.

Небольшой пример

Давайте в ASP.NET MVC 4 проект добавим файл greeter.ts c кодом, который добавляет на страницу кнопку и обрабатывает её нажатие:

class Greeter {
    greeting: string;

    constructor (message: string) {
        this.greeting = message;
    }

    greet() {
        return "Hello, " + this.greeting;
    }
}

var greeter = new Greeter("world");

var button = document.createElement('button');
button.innerText = "Say Hello";

button.onclick = function () {
    alert(greeter.greet())
}

document.body.appendChild(button);

После компиляции будет создан greeter.js:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
    alert(greeter.greet());
};
document.body.appendChild(button);

Для подключения созданного кода на страницу достаточно сослаться на js-файл в нужном Представлении:

<script src="~/Scripts/greeter.js"></script>

В завершении можно сказать, что первый шаг по модернизации JavaScript оказался успешным. Ждем продолжения и используем TypeScript в своих проектах.

Комментарии (26) -

Александр 03.10.2012 13:43:40

Интересно только одно: почему используютмя стиль а-ля Java (export/implements), а не С#? Было бы вообще удобно.

Очень непрофессионально в наглую перепечатывать статью, добавив 2 слова(

За ссылку на расширение для sublime спасибо
Расширение для студии http://goo.gl/cm1aG заработало без манипуляций с файлами проектов
При чем тут именно MVC4 не совсем понятно

@ Dk: Некрасиво обвинять без фактов и не подписавшись. Укажите ссылку на "оригинал".

@ SanSYS: Само расширение для редактора работает без проблем. Модификация .csproj нужна чтобы при сборке проекта выполнялась компиляция ts в js.

@ Andrey: хм.. ну это понятно, но js компилится при сохранении ts файла, хотя ваш вариант тоже не плох, по крайней мере, при необходимости добавить кучу чужих ts-файлов не придется все пересохранять )

Класс, обязательно буду использовать. Только один вопрос: как быть с отладкой на клиенте? Придется отлаживать на совсем свой код, а скомпилированный. Надеюсь это не вызовет особых проблем.

@ Вячеслав: Ну.. сам код функций и даже имена остаются прежними, так что не страшно - отлаживать можно

@ SanSYS: Сейчас из интереса создал MVC4 проект (шаблон Basic), добавил ts фaйл, заменил getDist() на getDist1() и сохранил (Ctrl+S). JS не изменился. Заменил весь код на Greeter, сохранил - не меняется. У вас точно компилируется при сохранении файла (в проекте без модификации)?

@ Вячеслав: Есть такое. Точку останова в ts не подставить. Но, как уже отметил SanSYS, отлаживать можно. Плюс, хочется надеяться что в будущих версиях появится возможность отладки именно ts-код.


SanSYS : установил обновление по вашей ссылке, однако .ts файлы после сохранения компилироваться даже не думают. Что я сделал не так?
Редактирование .csproj правда решает проблему, но приходится каждый раз делать ребилд, хотелось бы конечно делать это при сохранении.

Не понятно, как это завязать с jQuery и подобными, без этого сейчас никуда

hVostt :
Не понятно, как это завязать с jQuery и подобными, без этого сейчас никуда
Нужно вначале скрипта объявить переменную $ любого типа:
var $: any;

@ Вячеслав:

честно говоря сам подумал об этом «решении», но тогда в чем смысл TypeScript не понятно, JS без библиотек бесполезен. вряд ли jQuery озаботятся разработкой и сопровождением TypeScript версии библиотеки, не говоря уже о других. другое дело писать совершенно свой фреймворк, ни от чего не зависимый. в полку велосепедистов прибавиться.

Александр 04.10.2012 11:30:51

@hVostt:

You need to add a reference to the jQuery definition at the top of your .ts file.

/// <reference path="jquery.d.ts" />
You can find type annotations for jQuery in this sample: typescript.codeplex.com/.../jquery.d.ts

Столкнулся с проблемой: скомпилированные js файлы хранятся на сервере в кодировке ANSI вместо UTF-8, и как следствие браузеры не распознают кириллицу.
Попробуйте: alert("привет");
Кто-нибудь знает как с этим бороться?

Александр :
Это решает проблему но не полностью, т.к. данные аннотации не совсем корректны (надеюсь в будущем исправят).
Например объект JQueryXHR не имеет свойственных в jQuery методов, и поэтому работоспособный код не компилируется:
$.post(url).success(successFunc).error(errorFunc);

@ Вячеслав: Строки лучше хранить вне скрипта. Но баг такой есть.

Насчет jQuery - в баг-трекере уже есть сообщения. Сейчас версия 0.8, так что думаю к релизу должны доделать.

Валерий 04.10.2012 17:59:35

Чем хуже(лучше) Script# ???

@ Валерий: В первую очередь наличием внятных примеров для старта (документации на Script# по сути вообще нет). Если знаете такие (что-то в стиле Playground у TS) - подскажите.

Евгений Веприков 04.10.2012 22:56:09

WebSharper много круче, правда там F# компилируется в JavaScript, а порог вхождения в F# как минимум на порядок выше, чем в тот же C#.

Про отладку - можно вот как http://habrahabr.ru/post/153803/

Добрый день !

Создал проект ASP.NET MVC 4 в Visual Studio 2010.
Добавил в проект часть Вашего файла-greeter.js :

var Greeter = (function () {
function Greeter(message) {
     this.greeting = message;
    }
     Greeter.prototype.greet = function () {
     return "Hello, " + this.greeting;
    };
    return Greeter;
})();
В процессе компиляции проекта получил сообщение:
"Пространство имен не может содержать такие члены, как поля или методы" с
  указанием на тип var в строке : var Greeter = (function () {
Что нужно сделать, чтобы избаиться от этой ошибки ?

app

@ app: вы это в ts файл вставили? Опишите класс в ts синтаксисе.

Нет, это отдельный greeter.js - файл,
который включен в проект.
Но у меня возник вопрос: нужно ли создавать класс-"public class reeter",
если да, то где ?
app

@ app: Опишите что именно вы хотите сделать (можно в почту через форму контакта на этом блоге). По вашим сообщениям у меня сложилось впечатление что вы не совсем понимаете что делаете (или не так объясняете).

SanSYS :
За ссылку на расширение для sublime спасибо
Расширение для студии http://goo.gl/cm1aG заработало без манипуляций с файлами проектов
При чем тут именно MVC4 не совсем понятно


Для ASP.NET существует решение на базе Microsoft ASP.NET Web Optimization Framework (http://aspnetoptimization.codeplex.com), производящее компиляцию TypeScript-кода в JavaScript «на лету» (без использования Visual Studio). Просто установите Bundle Transformer (http://bundletransformer.codeplex.com) с модулем BundleTransformer.TypeScript (nuget.org/packages/BundleTransformer.TypeScript), а затем создайте и зарегистрируйте bundle`ы. Кроме того, Вы также можете установить один из модулей-минимизаторов, чтобы производить минимизацию сгенерированного JS-кода с помощью наиболее подходящего Вам алгоритма минимизации (на данный момент поддерживаются: Microsoft Ajax Minifier, YUI Compressor, Google Closure Compiler, JSMin, Packer и UglifyJS).

Также замечу, что при использовании BundleTransformer.TypeScript не возникает проблем с TS-файлами в кодировке UTF-8.

Andrey :
@ SanSYS: Сейчас из интереса создал MVC4 проект (шаблон Basic), добавил ts фaйл, заменил getDist() на getDist1() и сохранил (Ctrl+S). JS не изменился. Заменил весь код на Greeter, сохранил - не меняется. У вас точно компилируется при сохранении файла (в проекте без модификации)?

Возможно, что SanSYS использует VS-расширение Web Essentials 2012 (visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6), которое поддерживает компиляцию TS-файлов при сохранении.

Добавить комментарий