trouble importing components using href="package:..."

177 views
Skip to first unread message

phyton.dbd

unread,
Nov 27, 2013, 4:10:20 PM11/27/13
to w...@dartlang.org
I've created a failed_import.html example (https://github.com/patefacio/oops/blob/master/example/failed_import/failed_import.html) that shows an attempted import using the "package:..." format failing. According to this SO question (http://stackoverflow.com/questions/16206425/whats-the-best-way-to-import-components-via-link-tag-from-a-package), this should work.

In summary, using this works:
    <link rel="import" href="../packages/oops/components/oops_import.html">
but using this fails:
    <link rel="import" href="package:oops/components/oops_import.html">
with this error:
  Failed to load resource
    package:oops/components/oops_import.html
  warning: package:oops/components/oops_import.html not found.

One "feature" of what I am doing is putting examples under separate folders within example - so maybe this is a problem. But after doing the pub upgrade there is a packages folder under .../example/failed_import which does contain a folder called oops which contains the components.

Below is the structure picture from pub. The link in .../oops/packages/oops points to ../lib which seems correct.

Publishing "oops" 0.0.1 to https://pub.dartlang.org:
|-- .gitignore
|-- codegen
|   '-- oops.ebisu.dart
|-- example
|   |-- failed_import
|   |   '-- failed_import.html
|   |-- font_awesome
|   |   '-- font_awesome.html
|   '-- svg_use
|       '-- svg_use.html
|-- lib
|   '-- components
|       |-- oops.css
|       |-- oops_font_awesome.dart
|       |-- oops_font_awesome.html
|       |-- oops_import.dart
|       |-- oops_import.html
|       |-- oops_svg.dart
|       '-- oops_svg.html
'-- pubspec.yaml

Thanks
Dan

Siggi Cherem

unread,
Nov 27, 2013, 6:19:46 PM11/27/13
to w...@dartlang.org
Hey Dan,

Unfortunately this is a feature of web_ui that had to be removed in polymer. This is because in polymer we tried to avoid a compilation step to run in Dartium. This means that HTML imports are resolved directly by the browser, where there is no understanding of the special package: urls we have for Dart.

Dartium should work when you do "../../packages/oops" from your lib/ directory, or if you do "packages/oops/" from your web directory. The polymer-build process will also recognize this pattern.

Cheers,
Siggi


--
You received this message because you are subscribed to the Google Groups "Dart Web Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web+uns...@dartlang.org.
Visit this group at http://groups.google.com/a/dartlang.org/group/web/.

Matthew Butler

unread,
Nov 28, 2013, 8:24:54 AM11/28/13
to w...@dartlang.org


On Wednesday, November 27, 2013 7:19:46 PM UTC-4, sigmund wrote:
.... The polymer-build process will also recognize this pattern.

Cheers,
Siggi

Awesome! I wasn't aware of this factoid. Will need to keep that in mind for better organization of my polymer projects! Yay! \o/

Matt

phyton.dbd

unread,
Nov 28, 2013, 8:55:04 AM11/28/13
to w...@dartlang.org
Ok - sorry I'm struggling with this - but I'm trying to use one component from a different component library. Here is a setup:

bash-3.2$ find . | grep -v packages 
.
./pkga
./pkga/example
./pkga/example/an_example
./pkga/example/an_example/example.html
./pkga/lib
./pkga/lib/components
./pkga/lib/components/a.dart
./pkga/lib/components/a.html
./pkga/pubspec.lock
./pkga/pubspec.yaml
./pkgb
./pkgb/lib
./pkgb/lib/components
./pkgb/lib/components/b.dart
./pkgb/lib/components/b.html
./pkgb/pubspec.lock
./pkgb/pubspec.yaml


pkga has a component foo-a 

<!DOCTYPE html>
<link rel="import" href="../../packages/pkgb/lib/components/b.html">
<polymer-element name="foo-a">
  <template>
    I am an a
    which has a b
    <foo-b></foo-b>
  </template>
  <script type="application/dart" src="a.dart"></script>
</polymer-element>

with backend

library a;
import 'dart:html';
import 'package:polymer/polymer.dart';
 
@CustomTag("foo-a")
class A extends PolymerElement {
  A.created() : super.created() {
    print("Created A");
  }
}

pkgb has similar, but 'b' instead of 'a'. So, a uses b. The import in green above is specified correctly relative to where a.html is, but this does not seem to work. When I run the example.html, which looks like the following:

<!DOCTYPE html>
<html>
  <head>
    <link rel="import" href="../../packages/pkgb/components/b.html">
    <link rel="import" href="../../packages/pkga/components/a.html">
    <script type="application/dart">export 'package:polymer/init.dart';</script>
    <script src="packages/browser/dart.js"></script>
  </head>
  <body>
    First is a B
    <foo-b style="display: block; border: 3 double; background: beige"></foo-b>
    Then is an A
    <foo-a style="display: block; border: 3 double; background: beige"></foo-a>
  </body>
</html>

I get the following output:

Failed to load resource: the server responded with a status of 404 (Not Found)

Created B

Created B

Created A


Somehow an extra packages is showing up... what am I doing wrong?

Thanks
Dan

Siggi Cherem

unread,
Dec 9, 2013, 8:44:13 PM12/9/13
to w...@dartlang.org
Hey Dan,

Sorry for the slow response, I was out of town all of last week.

I just tried your example below and had to do some changes, but managed to get it working both in Dartium and with pub build. More details below...


On Thu, Nov 28, 2013 at 5:55 AM, phyton.dbd <phyto...@gmail.com> wrote:
Ok - sorry I'm struggling with this - but I'm trying to use one component from a different component library. Here is a setup:

bash-3.2$ find . | grep -v packages 
.
./pkga
./pkga/example
./pkga/example/an_example
./pkga/example/an_example/example.html

Note that currently pub-build doesn't do anything with the 'example' folder. If you want to build an application, the code would have to be in the 'web' folder (see issue 14673). I moved the example to 'web/' and added it to the transform section in the pubspec.

transformers:
- polymer:
    entry_points: web/an_example/example.html


./pkga/lib
./pkga/lib/components
./pkga/lib/components/a.dart
./pkga/lib/components/a.html
./pkga/pubspec.lock
./pkga/pubspec.yaml
./pkgb
./pkgb/lib
./pkgb/lib/components
./pkgb/lib/components/b.dart
./pkgb/lib/components/b.html
./pkgb/pubspec.lock
./pkgb/pubspec.yaml


pkga has a component foo-a 

<!DOCTYPE html>
<link rel="import" href="../../packages/pkgb/lib/components/b.html">

I had to fix this import: the relative path has to go up one more level (an extra '../') and exclude the 'lib' directory:
<link rel="import" href="../../../packages/pkgb/components/b.html">

 
<polymer-element name="foo-a">
  <template>
    I am an a
    which has a b
    <foo-b></foo-b>
  </template>
  <script type="application/dart" src="a.dart"></script>
</polymer-element>

with backend

library a;
import 'dart:html';
import 'package:polymer/polymer.dart';
 
@CustomTag("foo-a")
class A extends PolymerElement {
  A.created() : super.created() {
    print("Created A");
  }
}

pkgb has similar, but 'b' instead of 'a'. So, a uses b. The import in green above is specified correctly relative to where a.html is, but this does not seem to work. When I run the example.html, which looks like the following:

<!DOCTYPE html>
<html>
  <head>
    <link rel="import" href="../../packages/pkgb/components/b.html">
    <link rel="import" href="../../packages/pkga/components/a.html">

Here I just used packages with no "../../", as follows:

    <link rel="import" href="packages/pkga/components/a.html">


The rationale behind these fixes is easier to explain when you look at how pub packages are resolved. This becomes fairly clear when you look at the packages folder created in your 'build/' output after calling pub build, or when you look at the packages symlinks that are created in your file system on 'pub-get'.

Dart, dartium, and dart2js have the notion of 1 package root, by default this package root is located next to your entrypoint file. "package:" imports are resolved from there. The packages folder do not contain the original layout of your package, they just point directly to your 'lib' folder. That's why we had to exclude 'lib/' above.

In terms of your example, the layout looks as follows:

entry_point_folder/   // for instance web/an_example
|-- packages/
|  |-- pkga/
|  |   '-- components/
|  |       '-- a.html
|  |       '-- a.dart
|  |
|  '-- pkgb/
|      '-- components/
|          |-- b.html
|          '-- b.dart
|
|-- example.html
'-- example.dart

In Dart, you don't have to think about how to import one file from another package, you just use a 'package:' import and everything works. However, because HTML doesn't know about these special "package:" URLs, we have to do something else in polymer and link-rel imports. What we decided to do is to walk up to the 'packages' folder from whether you are, and then walk into the other package where you are loading the file from.

This is why we say that if you are in your entrypoint (your example.html above), then you should use 'packages' directly (no ../../). But if you are inside of 'lib/', then use a relative path to walk up all the way to 'packages/'. Typically this is just "../../packages" if the file is directly under 'lib', but in your example you had an extra folder ('components') so you need an extra "../".


phyton.dbd

unread,
Dec 21, 2013, 3:47:54 PM12/21/13
to w...@dartlang.org
Siggi,

Thanks very much for explaining this, it makes sense. In a similar project I have made suggested changes and I think they are good changes.

Regards,
Dan
Reply all
Reply to author
Forward
0 new messages