1

I try to understand how to use polymer with file structure which differs from default Pub/Dart structure (so tutorials doesn't help me here). I've read the following pages:

Here is my structure:

src/
 controllers/, models/, views/ #Go related files
 main.go #Go web server
 static/ #CSS, Images, Dart
   ...
   styles/
   scripts/
     packages/ #links to actual packages
     web/
       packages/ #link to ../packages
       ui-elements.html
       main.dart
     pubspec.yaml
   ...

src/views/index.html - site's index page

...
<head>
  <link rel="import" href="scripts/web/ui-elements.html"/>
</head>
<body>
  <ui-watch></ui-watch>
  <!-- Does it should come first or after polymer/init.dart? -->
  <script type="application/dart" src="scripts/web/main.dart"></script>
  <!-- path doesn't resolve correctly so I commented it and place initialization into the main.dart file itself -->
  <!--<script type="application/dart">export 'package:polymer/init.dart';</script>-->
  <script src="scripts/packages/browser/dart.js"></script>
</body>

src/static/scripts/web/main.dart

import 'dart:html';
import 'dart:async';
import 'package:polymer/polymer.dart';
export 'package:polymer/init.dart';

@CustomTag('ui-watch')
class UIWatch extends PolymerElement {
  @observable String counter = '00:00';

  UIWatch.created() : super.created();

  ButtonElement startWatch;

  @override
  void detached() {
    super.detached();

  }
}
main() {
  initPolymer();
}

src/static/scripts/web/ui-elements.html

<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="ui-watch">
  <template>
    <div>{{counter}}</div>
    <div>
      <button id="startWatch">Start</button>
    </div>
  </template>

  <!--<script type="application/dart" src="main.dart"></script>-->
</polymer-element>

After run, I get the following:

GET http://localhost:8080/packages/polymer/polymer.html 404 (Not Found)
Error loading html import from path `polymer.html`
Found bad packages uri in html import. All packages uris should point to the
packages symlink in the same folder as the entry point.

Entry point: http://localhost:8080/
Owner document: http://localhost:8080/scripts/web/ui-elements.html
Current import: <link rel="import" href="packages/polymer/polymer.html">
#I've already try this path, but I got the same error
Corrected import: <link rel="import" href="../../packages/polymer/polymer.html">

For more information, please see:
https://www.dartlang.org/polymer/app-directories.html#into-a-non-dart-non-entry-point

warning: http://localhost:8080/packages/polymer/polymer.html not found.

What's wrong here? I'm little bit confused how to organize these files.. Whatever I try paths doesn't resolve correctly. I think, one of the problem here that I don't understand what polymer/polymer.html and polymer/init.dart actually do as well as in what sequence the should be included.

Timur Fayzrakhmanov
  • 17,967
  • 20
  • 64
  • 95

2 Answers2

3

That won't work. If you deviate from the pub package structure pub build or pub serve will not be able to create a runnable Dart or JavaScript application.

If you want your go web server to serve the Dart client only the build output needs to be in the Directory go serves static content from, but not the Dart source files. They shouldn't be deployed anyway.

For development you should use a proxy or modify your go server to act as a proxy to forward all Dart related requests to pub serve.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • > For development you should use a proxy or modify your go server to act as a proxy to forward all Dart related requests to pub serve. | Could you explain this in more details, please.. – Timur Fayzrakhmanov Apr 12 '15 at 12:25
  • 2
    `pub serve` on-the-fly resolves paths, executes transformers and generates JS from Dart when JS is requested. If you load the Dart client (your index.html containing a Dart script) from your go server and the server serves the files directly from disk, these steps are omitted. Therefore your server should forward the requests to `pub serve` and serve the response to your browser. After you run `pub build` to generate JS output this isn't required anymore. You can just copy the `pub build` output into your servers static files directory. – Günter Zöchbauer Apr 12 '15 at 12:30
  • I think I got it. But what about using `export 'package:polymer/init.dart';` and `initPolymer()` in the dart file instead of placing the script tag with the `export 'package:polymer/init.dart';` in the index.html file directly? – Timur Fayzrakhmanov Apr 12 '15 at 12:39
  • 2
    The `polymer/init.dart` has a `main()` method. If your Dart application is a Polymer element `init.dart` does all the initialization and you don't need to care any further about `main()`. If you need additional initialization, for example when you also want to use Angular, your need a custom `main()` and then you must do the call to Polymer initialization in your `main()` (see http://stackoverflow.com/questions/20982489 for more details about custom main with Polymer). – Günter Zöchbauer Apr 12 '15 at 12:43
  • 2
    "Your Dart application is a Polymer element" means, you have Polymer element named for example `app-element` which contains your whole Dart application and then in `index.html` you only import `app_element.html` and your body contains only `` (your body can contain still contain additional non-Dart related stuff) – Günter Zöchbauer Apr 12 '15 at 12:46
  • Are there any benefits of using an application as whole Polymer element? If to be honest, stopwatch example from official Dart site doesn't even work on my iPhone 4s. Looks like Polymer has a very limited support.. – Timur Fayzrakhmanov Apr 12 '15 at 13:13
  • 2
    The main benefit is that you have all Polymer features (binding) available everywhere and you don't have to care whether you are within a Polymer element or not. You can also use auto-binding-dart (http://stackoverflow.com/questions/25838543) but I find it easier and more consistent to cope with "everything is an element" and don't have exceptions. As mentioned you don't need to care about Polymer initialization. Just put the content of main into `ready() { ... }` of `app-element`. I get the impression lately that (mobile) Safari becomes the new IE but I think it should work anyway. – Günter Zöchbauer Apr 12 '15 at 13:21
  • Gunter, please, could you give a little "Hello world" example using Polymer element as a whole Dart application, hence create `app-element`, especially how to organize files. Hardly imagine how to tie it all together (+ I need to use it with Go's template engine). I could create new question if it necessary. – Timur Fayzrakhmanov Apr 12 '15 at 19:42
  • This is a very basic example https://github.com/zoechi/dart_playground/tree/master/polymer/web/paper_dialog The `ready()` method in `app_element.dart` is missing though. What would you use Go's template engine for? – Günter Zöchbauer Apr 12 '15 at 19:53
  • Hm..I need play a little bit with your code to understand what's going on here. Go's template engine I use to split up layout on sections like `footer`, `header`, `nav` etc as well as to inject data from database. I like to use MVC ideology on server side. I'm totally tangled using Polymer..I think I need find some examples related to server side with Polymer. – Timur Fayzrakhmanov Apr 12 '15 at 20:23
  • Usually you don't do anything server-side with polymer but providing an API (REST) to fetch and post data. When Dart it built to JS everything is tree-shaken and minified. If you change something afterwards like binding expressions your app will break. – Günter Zöchbauer Apr 13 '15 at 04:09
  • 2
    I know that Polymer has nothing to do with server-side)) Thanks anyway, I try to do something with it and if it fails - I create new question) – Timur Fayzrakhmanov Apr 13 '15 at 13:20
3

This specific warning is about html import canonicalization. Browsers don't know about symlinks, so it is important that all html imports point to the same packages symlink otherwise files will be loaded twice and likely cause errors.

The way polymer enforces this is by requiring that all html imports to files in the packages folder go through the packages symlink at the same level as your entry point to the application, in your case it looks like this is src/static. However, pub doesn't know about that folder so there is no symlink there.

I have never tried this but you could try making a manual symlink called packages in the src/static folder and point it at scripts/packages. Then do what the warning suggests and change the html import in scripts/web/ui-elements.html by prepending a ../../. That way you are canonicalizing everything to the new symlink at src/static/packages.

This will have some other interesting side effects though, since you can't list your actual entry points in your polymer transformer... without knowing more about your app though its hard to tell exactly how that might affect things.

Jake MacDonald
  • 1,348
  • 6
  • 7