能否将 Dart 函数仅转换为 JavaScript?

5

我目前正在使用以下软件包,其中自述文件说明如下:

final bool loaded = await JsIsolatedWorker().importScripts(['test.js']);

我正在使用隔离 worker 包,使我的代码可以在 Web 上和 Web 之外工作。我想从我的 Dart 代码生成 JavaScript 代码。我有一个文件包含顶层函数,我使用

dart compile js -O0 -o test.js test.dart

我在这里找到了它

https://dart.dev/tools/dart2js

这是我的Dart文件

void main(List<String> args) {
  doComputation('');
}
            
String doComputation(String input) {
  return 'output';
}

如果我具有一个主要函数,我就能够生成JavaScript代码;但是,这会生成一个JavaScript文件,其中 doComutation 不是一个顶级函数,因此我不确定包是否可以调用该函数。它似乎生成整个程序而不是只生成一个函数。

生成的文件太长了,无法发布。

那么我的问题归结为:有没有一种方法可以从Dart中仅针对1个函数及其依赖项生成JavaScript,而不必生成整个程序?以便我可以从Dart中调用此函数。

3个回答

1

虽然我不是专家,但我也遇到了这个问题。以下是对我有效的解决方法:

在 web_worker.dart 中:

import 'package:js/js.dart';

main(){
  allowInterop(doComputation);
}

@JS('doComputation')
String doComputation(String computationInput) {
  // Replace this with your actual computation.
  final String computationOutput = "output";
  return computationOutput;
}

使用以下命令进行编译:

$ dart compile js web_worker.dart -o webWorker.js

请手动编辑由编译器生成的JS文件webWorker.js:

删除文件顶部的这一行:

(function dartProgram() {

并在文件底部与相应的闭括号对应的行:

})();

我不太理解这里在发生什么,但是我找到了在webWorker.js文件中作为对象"A"的属性被定义的doComputation()函数的JavaScript版本。

我在文件顶部定义了一个包装器,如下所示:

function doComputation(computationInput) {
  return A.doComputation(computationInput)
}

然后我就可以像这样使用JsIsolatedWorker来使用这个文件:

final bool loaded =
    await JsIsolatedWorker().importScripts(['../web/webWorker.js']);
if (loaded) {
  final String computationResult = await JsIsolatedWorker()
      .run(functionName: 'doComputation', arguments: computationInput);    
} else {
  debugPrint('Web worker is not available');
}

如果有更懂这个问题的人可以进一步阐述或改进解决方案,那就太好了。我其实不太明白自己在做什么。我只是希望通过分享我的成功经验来帮助其他人节省时间。请保留HTML标签。

-1

您可以使用js包从Dart代码调用JavaScript API,或反之亦然。要使Dart函数可通过名称从JavaScript调用,请使用带有@JS()注释的setter。

@JS()
library callable_function;

import 'package:js/js.dart';

/// Allows assigning a function to be callable from `window.functionName()`
@JS('functionName')
external set _functionName(void Function() f);

/// Allows calling the assigned function from Dart as well.
@JS()
external void functionName();

void _someDartFunction() {
  print('Hello from Dart!');
}

void main() {
  _functionName = allowInterop(_someDartFunction);
}

现在 JavaScript 代码可以调用 functionName()window.functionName()

请查看谷歌图表 https://github.com/google/chartjs.dart/tree/master/example 获取完整示例。

来自 dart2js "Helping dart2js generate better code" 的提示:

不要担心应用程序包含的库的大小。dart2js 编译器执行树摇以省略未使用的类、函数、方法等。只需导入所需的库,让 dart2js 去除不需要的部分即可。

关于此帖 https://stackoverflow.com/a/21124252/3733730


这样做是否意味着您将应用程序限制为仅使用js?因为该软件包仅支持Web。 - anonymous-dev
是的,它与 dart2js 相关。 - Alann Maulana
我正在寻找一种既支持Web又支持iOS/Android的方法。这就是为什么我想要一个隔离的工作线程来处理Web和iOS/Android之间的委派。我认为JS包将限制我的应用程序仅限于Web。如果我可以生成一个JS文件,那么我就可以让隔离的工作线程进行委派,而不必进行Web导入。 - anonymous-dev
这并没有解决问题。该函数被添加到主作用域而不是工作线程作用域。无法从工作线程中运行它。 - anonymous-dev

-1

你可以使用dart2js包来代替这个操作

首先,在你的main.dart文件中编写你想要实现的函数或命令,然后创建一个单独的dart文件来调用你想要调用的函数。这样就能解决你的问题了。虽然这是一个单独的文件,但它只会执行你需要执行的一个函数。


你能详细说明一下吗?我创建了一个单独的Dart项目。创建了一个Dart文件,在其中调用了我的函数。在main.dart中调用此函数。然后从我的问题中运行dart2js命令。这会产生与之前非常相似的输出,其中我得到一个JavaScript程序而不是JavaScript函数。 - anonymous-dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接