3
votes

I'd like to export a Dart API to JavaScript on browsers without a Dart VM. For example, given a class A:

class A {
  String name;

  A();

  A.withName(this.name);
}

I'd like to create a JavaScript object using the exported API with:

var a = new A();

An answer to my previous question pointed me to js-interop.

However, I'm not able to get the expected result when working through the README example. It appears that my Dart library isn't being exported into JavaScript.

pubspec.yaml:

name: interop
description: >
  A library useful for applications or for sharing on pub.dartlang.org.
version: 0.0.1
dev_dependencies:
  unittest: any
dependencies:
  js:
    git:
      url: git://github.com/dart-lang/js-interop.git
transformers:
  - js
  - js/initializer

example/main.dart

library main:

import 'package:js/js.dart';

main() {
  initializeJavaScript();
}

lib/a.dart

library a;

import 'package:js/js.dart';

@Export()
class A {
  String name;

  A();

  A.withName(this.name);
}

index.html

<html>
  <head>
    <script src="packages/js/interop.js"></script>
  </head>
  <body>
    <script type="application/dart" src="build/example/main.dart"></script>
  </body>
</html>

(It's not clear where the src attribute of that last script tag should point. I've tried using /example/main.dart as well, which doesn't change my result.)

I expected to be able to open a console after compiling (Tool -> Pub Build) and loading index.html, and then do this:

var a = new dart.a.A();

However, I get this instead: "Cannot read property 'A' of undefined". In other words, dart.a is undefined.

The inclusion of raw Dart script in index.html suggests that js-interop is intended for a browser with a Dart VM. I tried running index.html on Dartium with the same result.

What am I missing?

2

2 Answers

2
votes

The src attribute of the script tag still has to point to a file with a Dart script that contains a main() method. When the application is built to JavaScript using pub build Dart is compiled to JavaScript and can be run in browsers without a Dart VM.

2
votes

Yes, it does work on a JavaScript only browser. It turns out the documentation doesn't give all of the steps. Here's what worked for me, starting with a new project.

Create a new package project called 'jsout' using (File-> New Project/package). Delete these files:

  • test/all_test.dart
  • example/jsout.dart

Edit these files:

pubspec.yaml

name: jsout
description: >
  A library useful for applications or for sharing on pub.dartlang.org.
version: 0.0.1
dev_dependencies:
  unittest: any
dependencies:
  js:
    git:
      url: git://github.com/dart-lang/js-interop.git
transformers:
  - js
  - js/initializer

lib/main.dart

part of main;

@Export()
class A {
  String name;

  A();

  A.withName(this.name);

  talk() {
    print(name);
  }
}

Create folder web, and add these files:

web/main.dart

library main;

import 'package:js/js.dart';

part '../lib/jsout.dart';

main() {
  initializeJavaScript();
}

web/index.html

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <script src="main.dart_initialize.js"></script>
    <script src="main.dart.js"></script>
  </body>
</html>

After updating these files, load index.html, and open a console:

var a = new dart.main.A.withName('foo');

a.talk(); // returns 'foo'

This procedure worked as of revision 7afdb.