【发布时间】:2020-06-04 12:02:37
【问题描述】:
如果没有 - 是否有计划这样做?
我知道 dart 本身有不同的后端,可能有不同的实现。我很好奇用户是否可以这样做,例如有一个函数可以委托给一个 @patch 用于 js 运行时和另一个 @patch 在 dart vm 的情况下。
【问题讨论】:
标签: dart
如果没有 - 是否有计划这样做?
我知道 dart 本身有不同的后端,可能有不同的实现。我很好奇用户是否可以这样做,例如有一个函数可以委托给一个 @patch 用于 js 运行时和另一个 @patch 在 dart vm 的情况下。
【问题讨论】:
标签: dart
如果你正在创建一个包,你可以为不同的平台导出不同的实现,见这里:https://dart.dev/guides/libraries/create-library-packages#conditionally-importing-and-exporting-library-files
【讨论】:
制作平台特定代码(或者更确切地说是平台库特定代码)的方法是使用conditional imports。
语法是:
import "helper_default.dart"
if (dart.library.js) "helper_js.dart"
if (dart.library.io) "helper_io.dart";
此导入语句将导入三个库之一。如果dart:js 库在您正在编译的平台上可用,您将导入helper_js.dart。如果没有,并且dart:io 可用,那么您将导入helper_io.dart。如果那也不存在,您将导入helper_default.dart。
诀窍是在所有三个库中实现相同的库 API,但仅基于可用的平台库。
helper_js.dart 库可以使用 dart:js 来实现一些东西,helper_io.dart 可以导入 dart:io。默认库可能无法做任何有用的事情,因此如果您尝试使用它,它可能只会抛出 UnsupportedError。
导入库中的代码必须对所有三个导入都有效,这就是它们必须具有“相同”API 的原因。这可能包括声明一个类,但您通常会在三个实现可以共享的非平台相关库中定义该类的接口,以确保它们实际上具有相同的接口。
例子:
library mypkg.shared_types;
import "helper_default.dart"
if (dart.library.js) "helper_js.dart"
if (dart.library.io) "helper_io.dart"
as helper;
class SharedClass {
factory SharedClass(int something) = helper.SharedClassImpl;
int get value;
}
和
library mypkg.helper_io;
import "dart:io";
import "shared_types.dart";
class SharedClassImpl implements SharedClass {
int _id;
SharedClassImpl(this._id);
int get value { // Something depending on dart:io.
var bytes = File("pathToSomething-$id").readAsBytesSync();
return bytes[0];
}
}
【讨论】:
if (dart.library.js) 是否被认为是检测运行时是否为 js 的官方祝福方式?我可以将此答案链接到stackoverflow.com/questions/14655084/…
dart:js库是否可用的方法。这可能与在 JavaScript 上运行相关,但你不能绝对确定这将永远是正确的。 (技术上可以将 Dart 编译为 WASM 并在浏览器中运行它,可以使用 dart:js 集成库,但 Dart 本身不在 JS 中)。在代码中,您将使用const bool.fromEnvironment("dart.library.js") 来获取一个布尔值,当dart:js 库可用时,该值是正确的。可配置的导入语法对其条件进行隐式 Dart 环境查找。