Dart包的条件导入/代码

ALW*_*ALW 5 dart dart-mirrors

有什么方法可以根据环境标志或Dart中的目标平台有条件地导入库/代码吗?我正在尝试dart:io根据目标平台在ZLibDecoder / ZLibEncoder类和zlib.js 之间切换。

有一篇文章描述了如何创建一个统一的界面,但是我无法想象这种技术不会创建重复的代码,也不会创建冗余测试来测试该重复的代码。game_loop 使用此技术,但使用似乎不共享任何内容的单独类(GameLoopHtml和GameLoopIsolate)。

我的代码看起来像这样:

class Parser {
  Layer parse(String data) {
    List<int> rawBytes = /* ... */;
    /* stuff you don't care about */
    return new Layer(_inflateBytes(rawBytes));
  }
  String _inflateBytes(List<int> bytes) {
    // Uses ZLibEncoder on dartvm, zlib.js in browser
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望通过具有两个独立的类ParserHtml和ParserServer来避免代码重复,除了之外,它们都实现了相同的一切_inflateBytes

编辑:这里的具体示例:https : //github.com/radicaled/citadel/blob/master/lib/tilemap/parser.dart。这是一个TMX(磁贴图XML)解析器。

Fox*_*x32 5

您可以使用镜子(反射)来解决这个问题。pub 包路径dart:io正在使用反射在独立虚拟机或dart:html浏览器中访问。

来源位于此处。好处是,他们使用@MirrorsUsed,因此镜像 api 只包含所需的类。在我看来,代码的文档记录得非常好,应该很容易为您的代码采用该解决方案。

从 getter 开始_io_html在第 72 行声明),它们表明您可以加载库,而无需它们在您的 VM 类型上可用。如果库不可用,加载只会返回 false。

/// If we're running in the server-side Dart VM, this will return a
/// [LibraryMirror] that gives access to the `dart:io` library.
///
/// If `dart:io` is not available, this returns null.
LibraryMirror get _io => currentMirrorSystem().libraries[Uri.parse('dart:io')];

// TODO(nweiz): when issue 6490 or 6943 are fixed, make this work under dart2js.
/// If we're running in Dartium, this will return a [LibraryMirror] that gives
/// access to the `dart:html` library.
///
/// If `dart:html` is not available, this returns null.
LibraryMirror get _html =>
  currentMirrorSystem().libraries[Uri.parse('dart:html')];
Run Code Online (Sandbox Code Playgroud)

稍后您可以使用镜像来调用方法或 getter。current有关示例实现,请参阅 getter (从第 86 行开始)。

/// Gets the path to the current working directory.
///
/// In the browser, this means the current URL. When using dart2js, this
/// currently returns `.` due to technical constraints. In the future, it will
/// return the current URL.
String get current {
  if (_io != null) {
    return _io.classes[#Directory].getField(#current).reflectee.path;
  } else if (_html != null) {
    return _html.getField(#window).reflectee.location.href;
  } else {
    return '.';
  }
}
Run Code Online (Sandbox Code Playgroud)

正如您在评论中看到的,目前这只适用于 Dart VM。问题6490解决后,它也应该可以在 Dart2Js 中运行。这可能意味着该解决方案目前不适合您,但稍后会成为解决方案。

问题6943也可能有帮助,但描述了另一个尚未实现的解决方案。