use conditional imports to avoid dart:io imports on the web (#19)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 495379a..b8ad12b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.5
+
+* Use conditional imports to avoid dart:io imports on the web.
+
 ## 1.0.4
 
 * Set max SDK version to `<3.0.0`, and adjust other dependencies.
diff --git a/lib/src/package_root_resolver.dart b/lib/src/package_root_resolver.dart
index c9a06ff..4774a34 100644
--- a/lib/src/package_root_resolver.dart
+++ b/lib/src/package_root_resolver.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:io';
-
 import 'package:path/path.dart' as p;
 
 import 'async_package_resolver.dart';
@@ -48,12 +46,6 @@
     return Uri.parse("package:$relative");
   }
 
-  String packagePath(String package) {
-    if (packageRoot.scheme != 'file') return null;
-
-    var libLink = p.join(p.fromUri(packageRoot), package);
-    if (!new Link(libLink).existsSync()) return null;
-
-    return p.dirname(new Link(libLink).resolveSymbolicLinksSync());
-  }
+  String packagePath(String package) =>
+      packagePathForRoot(package, packageRoot);
 }
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 3e27cb4..5e4b411 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -6,12 +6,16 @@
 // exist.
 import 'dart:async';
 import 'dart:convert';
-import 'dart:io';
 import 'dart:isolate';
 
 import 'package:http/http.dart' as http;
 import 'package:package_config/packages_file.dart' as packages_file;
 
+// ignore: uri_does_not_exist
+import 'utils_stub.dart'
+    // ignore: uri_does_not_exist
+    if (dart.library.io) 'utils_io.dart' as conditional;
+
 /// Loads the configuration map from [uri].
 ///
 /// This supports `http`, `file`, `data`, and `package` URIs. If [client] is
@@ -24,8 +28,7 @@
   if (resolved.scheme == 'http') {
     text = await (client == null ? http.read(resolved) : client.read(resolved));
   } else if (resolved.scheme == 'file') {
-    var path = resolved.toFilePath(windows: Platform.isWindows);
-    text = await new File(path).readAsString();
+    text = await conditional.readFileAsString(resolved);
   } else if (resolved.scheme == 'data') {
     text = resolved.data.contentAsString();
   } else if (resolved.scheme == 'package') {
@@ -78,3 +81,6 @@
   if (uri.pathSegments.last.isEmpty) return uri;
   return uri.replace(pathSegments: uri.pathSegments.toList()..add(""));
 }
+
+String packagePathForRoot(String package, Uri root) =>
+    conditional.packagePathForRoot(package, root);
diff --git a/lib/src/utils_io.dart b/lib/src/utils_io.dart
new file mode 100644
index 0000000..8959f4d
--- /dev/null
+++ b/lib/src/utils_io.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+
+Future<String> readFileAsString(Uri uri) async {
+  var path = uri.toFilePath(windows: Platform.isWindows);
+  return await new File(path).readAsString();
+}
+
+String packagePathForRoot(String package, Uri root) {
+  if (root.scheme != 'file') return null;
+
+  var libLink = p.join(p.fromUri(root), package);
+  if (!new Link(libLink).existsSync()) return null;
+
+  return p.dirname(new Link(libLink).resolveSymbolicLinksSync());
+}
diff --git a/lib/src/utils_stub.dart b/lib/src/utils_stub.dart
new file mode 100644
index 0000000..cefa097
--- /dev/null
+++ b/lib/src/utils_stub.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+Future<String> readFileAsString(Uri uri) => throw UnsupportedError(
+    'Reading files is only supported where dart:io is available.');
+
+String packagePathForRoot(String package, Uri root) => throw UnsupportedError(
+    'Computing package paths from a root is only supported where dart:io is '
+    'available.');
diff --git a/pubspec.yaml b/pubspec.yaml
index ed21bf1..83ff8a5 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: package_resolver
-version: 1.0.4
+version: 1.0.5
 
 description: First-class package resolution strategy classes.
 author: Dart Team <misc@dartlang.org>