Conditional Importing

813 views
Skip to first unread message

Martin Charles

unread,
Feb 28, 2014, 11:17:52 AM2/28/14
to mi...@dartlang.org
I am trying to make an application that is capable of running on both the client and server. I need to make http requests in this application. Is it possible to conditionally import dart:io or dart:html to make this work?

William Hesse

unread,
Feb 28, 2014, 11:22:35 AM2/28/14
to General Dart Discussion
I think one solution to this problem has been to make two top level projects, one for dart:io and one for dart:html, and for them to both import a library that contains most of the shared code for your project.

Many people have been trying to solve this issue, so it would be good to hear from some of them about the solutions they have found.  Is there a better way?



On Fri, Feb 28, 2014 at 5:17 PM, Martin Charles <martinc...@gmail.com> wrote:
I am trying to make an application that is capable of running on both the client and server. I need to make http requests in this application. Is it possible to conditionally import dart:io or dart:html to make this work?

--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
William Hesse

Bob Nystrom

unread,
Feb 28, 2014, 11:43:06 AM2/28/14
to General Dart Discussion
On Fri, Feb 28, 2014 at 8:22 AM, William Hesse <whe...@google.com> wrote:
I think one solution to this problem has been to make two top level projects, one for dart:io and one for dart:html, and for them to both import a library that contains most of the shared code for your project.

That doesn't solve the problem, it just pushes it onto the library importing your project which now has to choose which one of those to import. If that library also wishes to be platform agnostic, it has to fork itself too and so on up the import chain.

We have this problem in the unittest package and that proposed solution has come up more times than I can count. It doesn't work. If I have a unittest that is itself platform-independent (i.e. it's testing code that only uses dart:core etc.) then importing "unittest_browser.dart" or "unittest_console.dart" breaks that.

Many people have been trying to solve this issue, so it would be good to hear from some of them about the solutions they have found.  Is there a better way?

I haven't seen anything I would describe as a solution.

The closest I've seen is that the path package used mirrors to effectively dynamically import either dart:io or dart:html based on availability. It had more or less the desired behavior, but was intolerably slow, caused a ton of code bloat and didn't work correctly in dart2js.

Cheers,

- bob

Peter Ahé

unread,
Mar 1, 2014, 3:57:27 AM3/1/14
to mi...@dartlang.org
We did consider making dart:io and dart:html always available, but "broken" where they don't make sense. This seems like such a simple solution to me, and I don't understand why it didn't get any traction.

Cheers,
Peter 
--

Gen

unread,
Mar 1, 2014, 4:35:43 AM3/1/14
to mi...@dartlang.org
Good idea for a bad situation.
 
It would be great if HTML or Dart VM would offer direct file access to a certain (restricted) part of the local filesystem; like a webserver server side.
I do not understand why that idea did not get any traction either.
That feature would make Dart clearly superior to Javascript; at least for a short time.
 
And it would be great to have the "html" package functional if there is a browser installed on the system. 
 
By "broken" you mean "null" or throwing exceptions ?

Lasse R.H. Nielsen

unread,
Mar 1, 2014, 5:39:23 AM3/1/14
to mi...@dartlang.org
On Sat, Mar 1, 2014 at 9:57 AM, Peter Ahé <a...@google.com> wrote:
We did consider making dart:io and dart:html always available, but "broken" where they don't make sense. This seems like such a simple solution to me, and I don't understand why it didn't get any traction.

The point where "dart:html" doesn't make sense without a browser is "everywhere'. 
The library is a wrapper around a DOM document, which you don't have in the server-side VM.
You will have neither "document" nor "window".
 
/L
--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

Alex Tatumizer

unread,
Mar 1, 2014, 10:46:32 AM3/1/14
to mi...@dartlang.org
My understanding is that all ilibrary-lelvel initializations in dart are lazy.
Which means html lib can be imported without errors regardless it's a browser or not, and it fails only on first access.
What if we can annotate import statement like @IKnowWhatImDoing import 'dart:html'?
 

Bob Nystrom

unread,
Mar 3, 2014, 11:48:53 AM3/3/14
to General Dart Discussion
On Sat, Mar 1, 2014 at 2:39 AM, Lasse R.H. Nielsen <l...@google.com> wrote:
The point where "dart:html" doesn't make sense without a browser is "everywhere'. 

Sure, the point is everywhere, but not necessarily everywhen. There's nothing broken in this program:

import 'dart:html';
import 'dart:io';

main() {
  if (const bool.fromEnvironment("SOMETHING_TRUE_IN_BROWSER")) {
    document.children.appendHtml("<p>In a browser!</p>");
  } else {
    stdout.writeln("On the command line!");
  }
}

But Dart currently prevents it from running. The problem is that imports are a static failure. If all Dart libraries were available on all platforms and threw at runtime, that would give us a lot more flexibility.

Cheers,

- bob

Günter Zöchbauer

unread,
Mar 3, 2014, 3:57:11 PM3/3/14
to mi...@dartlang.org
That's interesting because with types Dart follows a contrary philosophy. Even when they are wrong the app should run.
Also syntax problems in the application don't prevent it from being run (as long as the code is not executed).

Alex Tatumizer

unread,
Mar 3, 2014, 4:13:20 PM3/3/14
to mi...@dartlang.org
Early detection of "wrong" environment was obviously implemented with intention to HELP programmer. The possibility that it can HURT the programmer much more than it helps was probably overlooked.  Can you guys just admit a mistake and fix it?
It's such a PITA to deal with this issue...


John Messerly

unread,
Mar 3, 2014, 4:12:53 PM3/3/14
to General Dart Discussion
On Sat, Mar 1, 2014 at 2:39 AM, Lasse R.H. Nielsen <l...@google.com> wrote:
On Sat, Mar 1, 2014 at 9:57 AM, Peter Ahé <a...@google.com> wrote:
We did consider making dart:io and dart:html always available, but "broken" where they don't make sense. This seems like such a simple solution to me, and I don't understand why it didn't get any traction.

The point where "dart:html" doesn't make sense without a browser is "everywhere'. 
The library is a wrapper around a DOM document, which you don't have in the server-side VM.
You will have neither "document" nor "window".

Hmmm, I'm not sure about that. There are definitely reasons you'd want DOM on a command-line VM. For example, processing HTML files. We actually have such a library, as it turns out: http://pub.dartlang.org/packages/html5lib

I've been trying to make the APIs match dart:html when possible.

In an ideal world, it would implement enough of "dart:html" that you could use it for unit testing and server-side HTML generation of your client side app. That's been a little too far down on the priority list, but it would be really neat to see it happen. :)

John Messerly

unread,
Mar 3, 2014, 4:17:43 PM3/3/14
to General Dart Discussion
Also I'd argue the opposite makes sense too: having "dart:io" in the browser. If you look at the direction browsers are going with file system APIs, websockets, webrtc, workers, webgl, it seems like then trend is to expose OS capabilities in a secure way to web apps. And then there are things like Chrome Apps, which I'd imagine would get full powered "dart:io" and "dart:html".

Davy Mitchell

unread,
Mar 4, 2014, 3:13:27 PM3/4/14
to mi...@dartlang.org
Just to share my recent super simple experience...

I had a dependency on dart:html that was blocking my unit testing. To get round it, I created an abstract class (interface) for the drawing object (luckily just 3 methods used dart:html) and created a mock for testing and a real implementation for the web app.

Not at all convinced this would scale but may suit smallish projects.

Some interesting strategies above but even if they were available do they make sense when the unit test philosophy is to use mock objects? Not a unit testing expert so I could be very very wrong about this :-) Probably, as ever, depends on the scenario.

Cheers,
Davy


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--

Peter Ahé

unread,
Mar 4, 2014, 3:17:53 PM3/4/14
to General Dart Discussion


On Mar 1, 2014 10:35 AM, "Gen" <gp78...@gmail.com> wrote:
>
> Good idea for a bad situation.
>  
> It would be great if HTML or Dart VM would offer direct file access to a certain (restricted) part of the local filesystem; like a webserver server side.
> I do not understand why that idea did not get any traction either.
> That feature would make Dart clearly superior to Javascript; at least for a short time.
>  
> And it would be great to have the "html" package functional if there is a browser installed on the system. 
>  
> By "broken" you mean "null" or throwing exceptions ?
>  

Yes. I favor throwing exceptions.

Cheers,
Peter

Peter Ahé

unread,
Mar 4, 2014, 3:35:54 PM3/4/14
to General Dart Discussion


On Mar 1, 2014 11:39 AM, "Lasse R.H. Nielsen" <l...@google.com> wrote:
>
>
>
>
> On Sat, Mar 1, 2014 at 9:57 AM, Peter Ahé <a...@google.com> wrote:
>>
>> We did consider making dart:io and dart:html always available, but "broken" where they don't make sense. This seems like such a simple solution to me, and I don't understand why it didn't get any traction.
>
>
> The point where "dart:html" doesn't make sense without a browser is "everywhere'. 

That's not true, and besides the point.

It's besides the point because this solution isn't to share functionality between dart:io and dart:html. This is solely to provide a simple alternative to conditional imports.

It's not true because of things like HttpRequest and a ton of other API that is completely independent of HTML.

> The library is a wrapper around a DOM document, which you don't have in the server-side VM.
> You will have neither "document" nor "window".
>  

That's not how dart:html works. There's a bunch of classes in that library that are useful without a HTML document or a browser window. Most of these classes correspond to the worker API. See https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers

Cheers,
Peter

> /L
> --
> Lasse R.H. Nielsen - l...@google.com  
> 'Faith without judgement merely degrades the spirit divine'
> Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84
>

Peter Ahé

unread,
Mar 4, 2014, 3:47:41 PM3/4/14
to General Dart Discussion

I agree 100%, having an HTML parser masquerading as the DOM API would be awesome.

Should it be bundled with the standalone VM? Should it be a package? The easy answer is a package, but bundled with the VM even the constructors would work.

Cheers,
Peter

John Messerly

unread,
Mar 4, 2014, 5:13:13 PM3/4/14
to General Dart Discussion
Yeah, having it bundled as "dart:html" on standalone VM would be the most useful :). But I don't know if there'd be concerns around snapshot size and whatnot.

Thomas Schranz

unread,
Aug 15, 2014, 4:33:08 PM8/15/14
to mi...@dartlang.org
Just wanted to bump this thread up to see if there is a current best practice that I've overlooked.

I am currently writing my own UUID library (in order to play around with writing idiomatic dart as well as learning about UUID & implementations of it).

I would like to achieve all of the following with my uuid library:

* Support server vm, browser vm as well as dart2js usage
* Have only one true way to import the library (package:uuid/uuid.dart)
* Be able to use window.crypto.getRandomValues if available (in modern browsers: https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues)

Rationale: I don't want to put unnecessary burden on the user of my library

As far as I understand there is currently no way to pull this off?


What I've tried:

I've tried using mirrors similar to how the path package used to do different things depending on availability of dart:html or dart:io
but it seems like when the code is compiled using dart2js the LibraryMirror 'dart.dom.html' is not available (yet?).


Alternatives/Workarounds:

I could add my own random number generator and additionally allow the user to pass its own random number generator (eg window.crypto.getRandomValues).

This way at least it is possible to use the native browser random number generator (or any other one)
and even while I like that use-case in general and probably will add it (it is useful!) I really would like to use window.crypto.getRandomValues
as default if it is available and don't want to put the burden on the user to know about the possibility.

Any ideas/tips on this? :)

Bob Nystrom

unread,
Aug 15, 2014, 5:32:30 PM8/15/14
to General Dart Discussion

On Fri, Aug 15, 2014 at 1:33 PM, Thomas Schranz <tho...@blossom.io> wrote:
This way at least it is possible to use the native browser random number generator (or any other one)
and even while I like that use-case in general and probably will add it (it is useful!) I really would like to use window.crypto.getRandomValues
as default if it is available and don't want to put the burden on the user to know about the possibility.

Any ideas/tips on this? :)

There's no great answer for this right now. We're working on a solution here, but it may be a while before it bears fruit.

We've run into this problem a few times. The least bad solution we've come up with is to use mirrors. That at least does let you write code that uses "dart:html" in the browser but also runs on the standalone VM. With judicious use of @MirrorsUsed(), you can usually make this go without hurting your dart2js codesize too much, but that gets into dangerous waters.

It's super annoying. This problem has been bugging me for literally years and it's only very recently that we've started to get any traction with the team to address it.

Cheers,

- bob

Reply all
Reply to author
Forward
0 new messages