# TypeScript Monkey [![Build Status](https://api.travis-ci.org/markeissler/typescript-monkey.svg?branch=feature/typescript-monkey)](https://travis-ci.org/markeissler/typescript-monkey) [![Coverage Status](https://coveralls.io/repos/github/markeissler/typescript-monkey/badge.svg?branch=feature%2Ftypescript-monkey)](https://coveralls.io/github/markeissler/typescript-monkey?branch=feature%2Ftypescript-monkey) This is a TypeScript transpiler engine for the Rails asset pipeline. >BETA: TypeScript Monkey is currently in pre-release. That doesn't mean it's not ready for production, it just means it hasn't been tested by a large audience yet. The more the merrier and the faster we get to v1.0. Install it, open issues if you find bugs. ## Overview TypeScript Monkey let's you use TypeScript (files with a `.ts` extension) wherever you can use JavaScript (`.js`) files. This includes support for pre-processing other template formats. For instance, you can also create `.ts.erb` files. In essence, TypeScript is a first class citizen on Rails! For more information on TypeScript visit the [TypeScript](http://www.typescriptlang.org/) homepage. ## Requirements ### Node.js One of the goals of __TypeScript Monkey__ is to reduce the dependence on third-party gems which aren't under active development. This gem does require that [Node.js](https://nodejs.org/) has been installed either globally or locally. Specifically, TypeScript support (language and compiler) is provided by the TypeScript package for Node. If installed locally, it is not recommended that you commit your `node_modules` directory to source control. If you're not familiar with Node.js don't worry, it's not that scary. To install Node.js support, our recommendation is to use an appropriate package manager: [Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/) #### Recommended package managers For MacOS, our recommendation is [Homebrew](https://brew.sh/); for Windows your best bet is probably [Chocolatey](http://chocolatey.org/). Go and install a package manager first, then install node, then come back here. If you're on Linux, well, the assumption is that you probably know what you're doing already! >NOTE: Another obvious choice for Windows is [NuGet](https://www.nuget.org/) but it appears that the Node package there is stale. ## Installation ### Adding a Node Package Definition (package.json) File The first step is to create a Node.js `package.json` file at the root of your Rails project. You may have created this file already for other uses, if so, then you will need to merge in the following dependencies: ```json "dependencies": { "@types/jquery": "^2.0.41", "@types/node": "^7.0.14", "typescript": "^2.3.1" } ``` If you don't have an existing `package.json` you can use the `example_package.json` file in the [contrib](./contrib/) directory as a starting point. Copy the file to the `root` of your Rails project. __Be sure to rename the file as simply "package.json".__ The second step is to install some TypeScript dependencies with the Node.js package manager (`npm`): ```sh >npm install ``` The package manager will determine and install the dependencies noted above by reading the `package.json` file. ### Adding the Gem to your Rails Project's Gemfile Update your Gemfile to include the following statement: ```ruby # typescript support in the asset pipeline! gem 'typescript-monkey', '~> 0.9.0' ``` Then run bundler: ```sh >bundle install ``` Finally, restart your Rails server to load the __Typescript Monkey__ gem. ## Usage ### TypeScript Triple-Slash Directives __Typescript Monkey__ parses Typescript files and examines __Triple-Slash__ directives (also known as __reference__ tags or comments). For each directive, a Sprockets dependency relationship will be created so that a change in a dependency will trigger Sprockets to re-process the dependent file as well. >NOTE: __TypeScript Monkey__ does not currently support _import_ directives. See [Features Not Yet Implemented (but on the way)](#pending-features) for more information. Learn more about __Triple-Slash__ directives by referring to the following secction of the __Typescript Spec__: [Source Files Dependencies](https://github.com/teppeis/typescript-spec-md/blob/master/en/ch11.md#1111-source-files-dependencies) ### In the Asset Pipeline (Sprockets) Typical usage is the same as with JavaScript. That is, you will need to add your TypeScript files to `.js` manifest files just like you would with JavaScript. For instance, in the below example let's pretend that you have created the following: ```sh app/assets/javascripts/ ├── application.js ├── my-typescript-files └── superduper.ts ``` #### File example: superduper.ts ```ts class SuperDuper { public message(message: string): void { const body: HTMLBodyElement = document.getElementsByTagName("body")[0]; const element = document.createElement("p"); element.innerHTML = `${message}`; body.appendChild(element); } } $(() => { const superduper = new SuperDuper(); superduper.message("TypeScript at work."); }); ``` Then, your `application.js` file might look like this: #### File example: application.js ```js // This is a manifest file that'll be compiled into application.js, which will include all the files // listed below. // // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. // // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // compiled file. // // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details // about supported directives. // //= require jquery //= require jquery_ujs //= require jquery-ui/core //= require bootstrap-sprockets //= require my-typescript-files/superduper ``` ### Embedded in \ tags Yes, you can embeded TypeScript in your templates just like JavaScript! All that's required is __TypeScript Monkey__ DYnamic Runtime Transpiler (aka __"dyrt"__). For example, let's say you had the following snippet in your template: ```erb ``` The key is making sure your `