You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Dart转JS编译器导出API并保持原API与JS API的直接映射?

Dart与JS的标准双向互操作方案说明

首先明确一点:官方确实支持JS调用Dart的标准方案,只是它不像Dart调用JS那样直观,也没有实现原Dart API到转译后JS API的自动直接映射——这部分确实是当前的局限,但绝非只能依赖hack手段。

官方标准实现方式:通过package:js暴露Dart实体到JS环境

dart:js和package:js的文档强调"单向",更多是指默认的互操作设计偏向Dart主动调用JS,但反向调用的能力是官方认可并支持的,核心思路是把Dart的函数、类实例主动挂载到JS的全局作用域(比如window对象),让JS可以直接访问。

1. 暴露Dart函数给JS

import 'package:js/js.dart';

// 声明JS全局作用域的一个变量,用于接收Dart函数
@JS()
external set jsCallableDartFunc(Function func);

// 普通的Dart函数
void greetFromDart(String name) {
  print(`Hello ${name}! This is Dart speaking.`);
}

void main() {
  // 使用allowInterop包装Dart函数,让它能被JS调用
  jsCallableDartFunc = allowInterop(greetFromDart);
}

转译后,JS里就可以直接调用:

window.jsCallableDartFunc("JS Developer");

2. 暴露Dart类实例及方法给JS

如果需要让JS调用Dart类的方法,同样可以把实例挂载到全局作用域:

import 'package:js/js.dart';

@JS()
external set dartClassInstance(MyDartClass instance);

class MyDartClass {
  String _message = "Default message from Dart";

  void updateMessage(String newMsg) {
    _message = newMsg;
  }

  String getMessage() {
    return _message;
  }
}

void main() {
  var dartInstance = MyDartClass();
  dartClassInstance = dartInstance;
}

JS端调用示例:

window.dartClassInstance.updateMessage("Hello from JS!");
console.log(window.dartClassInstance.getMessage()); // 输出 "Hello from JS!"

如果方法涉及this绑定问题(比如在JS中作为回调传递),可以使用allowInteropCaptureThis替代allowInterop来确保this指向正确的Dart实例。

关于"直接映射原Dart API"的局限

目前官方确实没有提供自动把整个Dart库的API直接映射为JS可调用API的机制——你没法像给JS对象加@JS()注解那样,给Dart类加注解就让它自动在JS环境中成为可实例化的类。这部分需要开发者手动暴露需要的实体,是当前互操作的一个小痛点,但手动暴露的方式是完全标准的,绝非hack。

总结

  • 不存在完全自动的Dart到JS API直接映射,但有官方支持的标准双向互操作方案;
  • 核心是通过package:js的allowInterop/allowInteropCaptureThis工具,将需要被JS调用的Dart函数、实例挂载到JS全局作用域;
  • 这种方式并非网上提到的复杂hack,而是官方文档隐含支持的标准用法。

内容的提问来源于stack exchange,提问作者user3464741

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:04:44