3

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?

Community
  • 1
  • 1
Rich Apodaca
  • 28,316
  • 16
  • 103
  • 129

2 Answers2

2

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.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks, that's good to know. Given that, any ideas as to where my setup is going wrong? – Rich Apodaca Dec 05 '14 at 21:55
  • I didn't use this package yet but I know you need to run `pub build` to get JavaScript from Dart and the `main.dart` file the `src` file points to must not be in the `build` directory. When you run `pub build` the `build` directory is purged. The `main.dart` file should be in the `web` directory and the `src` attribute should just be `src="main.dart` – Günter Zöchbauer Dec 05 '14 at 22:00
  • Thanks for the tip. I added a 'web' directory and moved index.html there. Edited src to point to "main.dart". I can "Run" index.html, and a server starts up. However, the problem remains. dart.a is undefined after loading the page. No errors appear on the page, and many dart files get loaded when I load the page, as evidenced from "Tool Output" within Dart Editor. – Rich Apodaca Dec 05 '14 at 22:23
  • Thanks to your answer, I was able to find a solution to the problem http://stackoverflow.com/a/27326963/54426 – Rich Apodaca Dec 06 '14 at 00:49
2

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.

Rich Apodaca
  • 28,316
  • 16
  • 103
  • 129
  • Why do you have `main.dart.js' as script source. You don't even have such a file. I think you should reference the `main.dart` file here. `pub build` or `pub serve` should replace this on the fly when loaded from a non-Dart capable browser. – Günter Zöchbauer Dec 06 '14 at 09:30
  • That approach worked when running Dartium, but not Chrome. In the latter case, an error was thrown when the constructor was run. That error disappeared when using the javascript files. – Rich Apodaca Dec 06 '14 at 15:29
  • When you load `index.html` from `build/web` generated by `pub build`? Can you post the error message? Did you try it with `pub serve` (or launch from DartEditor which used `pub serve` behind the curtains). – Günter Zöchbauer Dec 06 '14 at 15:33
  • functionmain.dart_initialize.js:36 Uncaught TypeError: undefined is not a function This error was received after command-R on the index.html file from Dart Editor. It started a server instance and Dartium. After trying in dartium, I loaded the same URL localhost:8081/index.html in Chrome, opened the console and attempted to instantiate dart.jsout.A.withName('foo'). – Rich Apodaca Dec 06 '14 at 15:42
  • I just saw that this line `part '../lib/jsout.dart';` is very wrong ;-) You must not go out of a top level folder like `web`, `bin`, `lib`, ... to import from another top level folder. You can only import files from within the current top level folder or from `lib` using the form `import 'package:jsout/jsout.dart';` – Günter Zöchbauer Dec 06 '14 at 15:47
  • See also https://www.dartlang.org/polymer/app-directories.html (some things are Polymer only but most of it should apply to all Dart web apps). – Günter Zöchbauer Dec 06 '14 at 15:50
  • I've fixed the part about '../lib/jsout.dart'. The error I reported in the last comment applies to that fixed version. Feel free to have a look at the repo on Github and suggest changes from there. https://github.com/rapodaca/jsout – Rich Apodaca Dec 06 '14 at 15:57