Iasi code camp 12 october 2013 typescript vs coffeescript - vlad iliescu
How we migrated our huge AngularJS app from CoffeeScript to TypeScript
-
Upload
luka-zakrajsek -
Category
Technology
-
view
577 -
download
2
Transcript of How we migrated our huge AngularJS app from CoffeeScript to TypeScript
![Page 1: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/1.jpg)
HOW WE MIGRATED OUR HUGE ANGULAR.JSAPP FROM COFFEESCRIPT TO TYPESCRIPT
Luka Zakrajšek
CTO @ Koofr
@bancek
Ljubljana Spring-ish JavaScript Meetup
February 10, 2015
![Page 2: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/2.jpg)
ABOUT MEFRI graduateCTO and cofounder at Koofr
frontend, backend, iOS, Windows Phonealmost 3 years of Angular.js
![Page 3: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/3.jpg)
KOOFRKoofr is white-label cloud storage solution for ISPs
![Page 4: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/4.jpg)
ANGULAR.JS AT KOOFRweb app
desktop application(web app wrapped into browser to look like native)
![Page 5: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/5.jpg)
HUGE APP?26 route controllers90 directives22 factories14 filters15 services
6012 LOC of Coffee (30 files)
2937 LOC of Angular HTML templates (101 files)
![Page 6: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/6.jpg)
WE WERE HAPPY WITH COFFEESCRIPTPros
clean codeclasses
Cons
technical debtfear of refactoringnot enough tests
![Page 7: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/7.jpg)
COFFEESCRIPTLaunched in 2010.
Gained traction with Rails support in 2011
$(function() { // Initialization code goes here})
$ -> # Initialization code goes here
![Page 8: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/8.jpg)
BROWSERIFYLets you require('modules') in the browser by bundling up all of your
dependencies.
var unique = require('uniq');var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];console.log(unique(data));
$ npm install uniq$ browserify main.js -o bundle.js
<script src="bundle.js"></script>
![Page 9: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/9.jpg)
TYPESCRIPTa typed superset of JavaScript that compiles to plainJavaScript
any existing JavaScript program is also valid TypeScriptprogram
developed by Microsoft
from lead architect of C# and creator of Delphi and TurboPascal
![Page 10: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/10.jpg)
FIND A TYPO
class Point { x: number; y: number; constructor(x: number, y: number) { this.x = x; this.y = y; } getDist() { return Math.sqrt(this.x * this.x + this.y * this.y); }}
var p = new Point(3,4);var dist = p.getDst();alert("Hypotenuse is: " + dist);
![Page 11: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/11.jpg)
FEATURES
![Page 12: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/12.jpg)
JAVASCRIPT
function Greeter(greeting) { this.greeting = greeting;}Greeter.prototype.greet = function() { return "Hello, " + this.greeting;}
// Oops, we're passing an object when we want a string.var greeter = new Greeter({message: "world"});
alert(greeter.greet());
![Page 13: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/13.jpg)
TYPES
function Greeter(greeting: string) { this.greeting = greeting;}
Greeter.prototype.greet = function() { return "Hello, " + this.greeting;}
var greeter = new Greeter("world");
alert(greeter.greet());
![Page 14: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/14.jpg)
CLASSES
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; }}
var greeter = new Greeter("world");
alert(greeter.greet());
![Page 15: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/15.jpg)
TYPES
class Animal { constructor(public name: string) { } move(meters: number) { alert(this.name + " moved " + meters + "m."); }}
class Snake extends Animal { constructor(name: string) { super(name); } move() { alert("Slithering..."); super.move(5); }}
var sam: Animal = new Snake("Sammy the Python");sam.move();
![Page 16: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/16.jpg)
GENERICS
class Greeter<T> { greeting: T; constructor(message: T) { this.greeting = message; } greet() { return this.greeting; }}
var greeter = new Greeter<string>("Hello, world");alert(greeter.greet());
![Page 17: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/17.jpg)
MODULES
module Sayings { export class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } }}var greeter = new Sayings.Greeter("world");alert(greeter.greet());
![Page 18: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/18.jpg)
USAGE
npm install -g typescript
tsc helloworld.ts
<script src="helloworld.js"></script>
Or Grunt, Gulp ...
![Page 19: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/19.jpg)
TOOLSincluded in Visual StudioJetBrains (IntelliJ)VimEmacsSublime TextCATS
![Page 20: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/20.jpg)
MIGRATIONcoffee-script-to-typescript to the rescue
npm install -g coffee-script-to-typescritpt
coffee-to-typescript -cma your/files/*.coffee
![Page 21: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/21.jpg)
EXISTING LIBRARIESwe use more than 30 libraries
to be completely type-safe,you need definitions for all external libraries
DefinitelyTyped - more than 700 librarieshttps://github.com/borisyankov/DefinitelyTyped
![Page 22: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/22.jpg)
EXAMPLEjgrowl.d.ts
/// <reference path="../jquery/jquery.d.ts" />interface JQueryStatic { jGrowl: jgrowl.JGrowlStatic;}declare module jgrowl { interface JGrowlOptions { sticky?: boolean; position?: string; beforeOpen?: Function; // ... } interface JGrowlStatic { (msg: string, options?: JGrowlOptions): void; }}
$.jGrowl({ sticky: true, beforeOpen: () => { console.log("opening") } })
![Page 23: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/23.jpg)
ANGULARJS - BEFORECoffeeScript
angular.module('comments.controllers', []).directive('comments', -> restrict: 'E' scope: mount: '=' replace: yes templateUrl: 'comments/comments.html' controller: ($scope, Api) -> $scope.comments = []
$scope.load = -> Api.call Api.api.Comments.commentsRange($scope.mount.id, 0, 10) success: (res) -> $scope.comments = res.comments
$scope.load())
![Page 24: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/24.jpg)
ANGULARJS - AFTERTypeScript
/// <reference path="../app.ts" />
module comments {
interface CommentsScope extends ng.IScope { mount: k.Mount comments: Array<k.Comment> load(): void }
![Page 25: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/25.jpg)
export class CommentsCtrl { constructor($scope: CommentsScope, Api: api.Api) { $scope.comments = [];
$scope.load = () => { Api.get(Api.api.Comments.commentsRange($scope.mount.id, 0, .then((res) => { $scope.comments = res.comments; }); } }; } }
![Page 26: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/26.jpg)
export var commentsDirective: ng.IDirectiveFactory = () => { return { restrict: "E", scope: { mount: "=", appendComment: "=" }, replace: true, templateUrl: "comments/comments.html", controller: CommentsCtrl }; };}
![Page 27: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/27.jpg)
PROJECT STRUCTURE
files/comments/utils/...app.tsmain.d.tstypings.d.ts
![Page 28: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/28.jpg)
PROJECT STRUCTUREapp.ts
/// <reference path="main.d.ts" />/// <reference path="files/index.ts" />/// <reference path="comments/index.ts" />/// <reference path="utils/index.ts" />
export var module = angular.module("app", [ "gettext",
files.module.name, comments.module.name, utils.module.name ])}
![Page 29: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/29.jpg)
PROJECT STRUCTUREcomments/index.ts
/// <reference path="../app.ts" />
/// <reference path="commentsDirective.ts" />
module comments { export var module = angular.module("comments", []) .directive("comments", commentsDirective);}
![Page 30: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/30.jpg)
HOW TO TEST EVERYTHING?code coverage to the rescue
usually used for test code coverage
we can use it to see which lines were covered by manually"testing" the app
![Page 31: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/31.jpg)
LIVECOVERNot published yet. Will be on GitHub and npm.
# Generate annotated JavaScript code with Blanket.js$ simple-blanket -o app-cover.js app.js
# Run LiveCover server$ livecover -p 3000
<script src="http://localhost:3000/coverage.js"></script>
Open in your browser and start clicking like crazy.
https://localhost:3000
![Page 32: How we migrated our huge AngularJS app from CoffeeScript to TypeScript](https://reader030.fdocuments.net/reader030/viewer/2022032421/55a668541a28abc5668b464c/html5/thumbnails/32.jpg)
QUESTIONS?