Dart2Ts

Dart2Ts is exactly what you are thinking : a Dart to TypeScript transpiler/compiler.

Dart2Ts is somewhat similar to dartdevc because both - in the end - will produce readable and modular javascript code but they differ in many fondamental aspects:

This last point allows us to use dart written code in typescript project seamless and viceversa and also allows us to focus on the semantically equivalence of the transpiler instead of optimization and javascript language level compatibility because for that we can leverages the typescript compiler.

Goals

The main goal of dart2ts is to provide a new way of developing application using the dart language in a tight integration with the most common and best of the breed javascript developing tools/environments like, for example:

We also want to provide a production ready development tool that can produce optimized and modular native javascript code and to provide an easy way to interoperate between dart code and typescript code in order to leverage the best advantages from both frameworks.

Usage

You can user dart2ts as a command line tool or as Builder in a build build step.

To use dart2ts command line tool you have to install it :

pub global activate -s git https://github.com/polymer-dart/dart2ts.git

Then you can use dart2ts from the command line :

dart2ts build
dart2ts build -d <path to your package>
dart2ts build -w # watches and incrementally rebuilds

To use dart2ts as a buildstep just add dart2ts dev dependency to your project and write a build.dart script; for instance:

    import 'package:dart2ts/dart2ts.dart';
    import 'package:build_runner/build_runner.dart';
    import 'package:build/build.dart';

    void main(List<String> args) {
      build([
         new BuildAction(new Dart2TSBuilder(),'mypackage'),
      ]);
    }

Developing with Dart2Ts

A dart2ts package is both a dart / pub package, and yarn/npm/typescript package; for this reason we have to provide project descriptors for each tool/language:

From the dart side your package will appear as a normal dart package with ./lib, ./web, ./test folders and a pubspec.yaml file. From the typescript side it will appear as a package with all the code in a ./lib subfolder.

“Light” Dart SDK

Dart is not only a language but also a rich API framework. In order to make dart2ts code work we have to provide a minimal version of the SDK (for example collections, async). The general approach here is to map as long as possible every data structure with the most natural JS native one and to leverage @JS interoperability for everything related to the platform (package:html5 instead of dart:html, and so on).

When possible we “convert” data structure during the compile phase. For example :

We also try to map async constructs with the equivalent typescript/es6 constructs, Iterable<X> with the javascript “iterable protocols”.

For the rest we provide a “minimal”, very incomplete, version of the dart_sdk in the form of a native separate typescript modules, one for each dart: package:

As a result of this approach the generated ts code will be more similar to the code you would end up writing if you choose to do it in typescript from the beginning.

Project structure

The project structure is basically the same of a tipical dart package but with some added descriptor for npm and typescript.

In the future we will automatically generate the package.json and tsconfig.json files if they are missing.

pubspec.yaml

The same as a normal pubspec.yaml. For instance:

name: dart2ts_test
description: sample_project to be translated
version: 0.0.1
dependencies:
 js: any
 html5:
  path: ..

tsconfig.json

Put your compile for typescript options here just like a normal typescript project keeping in mind that all your source code will be in the “dart” folders: ./lib, ./web, ./test.

package.json

Write your package.json replicating the dependencies of the pubspec.yaml (you can leave out package:js if used), adding dart_sdk and providing the same package name:

{
  "name": "dart2ts_test",
  "version": "1.0.0",
  "description": "a test for it",
  "main": "lib/index.html",
  "scripts": {
    "build": "webpack --config webpack.config.js",
    "serve": "webpack-dev-server --config webpack.config.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dart_sdk": "file:../../dart2ts/dart_sdk/",
    "html5": "file:../"
  },
  "devDependencies": {
    "ts-loader": "^2.3.7",
    "typescript": "^2.5.2",
    "webpack": "^3.6.0",
    "webpack-dev-server": "^2.8.2"
  }
}

webpack.config.js (optional)

If your package is an application package (it has a web folder), you can use webpack instead of tsc to produce the final output and to serve. See the demo for an example on how to do this.

Building

To build a dart2ts project you have to issue two command :

  1. dart2ts build : this will translate the .dart code to .ts
  2. tsc/webpack : this will translate the .ts code to the final .js code

Serving

During the developing phase you can leverage the power of webpack-dev-server to serve your app and have code changes automatically reloading the page. Do do this you have to both launch dart2ts in “watch” mode and webpack-dev-server :

  1. dart2ts build -w
  2. yarn run serve (see the demo for a package.json configuration that will launch the webpack-dev-server)

Demo

The demo shows a dart2ts, yarn, webpack example of integration. The demo will define a new custom element and uses it in the “Hello world” page.

See the demo in action: