Is it possible to only convert a dart function to javascript
Asked Answered
R

4

6

I am currently using the following package where the readme illustrates the following

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

I am using the isolate worker package so my code can work on web and outside of web. I would like to generate javascript code from my dart code. I have one file with a top level function and I use

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

which I found here

https://dart.dev/tools/dart2js

this is my dart file

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

I can generate javascript only if I have a main function but this generates a javascript file where the doComutation is not a top level function, so I am not sure if the package can call the function. It looks like it generates an entire program instead of just generating one function.

The generated file is too long to post

So what my question comes down to is this. Is there a way to generate javascript from dart for 1 function with its dependencies included instead of having to generate the entire program? So that I can call this function from dart.

Rosebud answered 3/6, 2022 at 22:27 Comment(0)
P
1

I am not an expert but I also had this problem. Here's what worked for me:

In 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;
}

Compile it using:

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

Manually edit webWorker.js, the JS file generated by the compiler:

Delete this line at the top of the file:

(function dartProgram() {

and the line at the bottom of the file with the corresponding closing brace:

})();

I don't understand what's going on here but I found the Javascript version of the function doComputation() defined in webWorker.js as a property of the object "A".

I defined a wrapper at the top of the file like this:

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

and then I was able to use the file with JsIsolatedWorker like this:

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');
}

If someone who understands this better can elaborate or improve on this solution, that would be great. I don't really have any idea what I'm doing. I'm just posting this to hopefully help other people save time in the future by sharing what worked for me.

Pursuit answered 8/1, 2023 at 5:58 Comment(0)
P
0

You can use js package to call JavaScript APIs from Dart code, or vice versa. To make a Dart function callable from JavaScript by name, use a setter annotated with @JS().

@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 code may now call functionName() or window.functionName().

Check google chartjs https://github.com/google/chartjs.dart/tree/master/example for a complete example.

From dart2js "Helping dart2js generate better code" there is a tip :

Don’t worry about the size of your app’s included libraries. The dart2js compiler performs tree shaking to omit unused classes, functions, methods, and so on. Just import the libraries you need, and let dart2js get rid of what you don’t need.

Related to this post https://mcmap.net/q/1918722/-dart2js-producing-large-javascript-files-even-with-little-code.

Preselector answered 10/6, 2022 at 2:4 Comment(4)
Does doing this mean you limit your application to js? Because the package has web support onlyRosebud
Yes it is, related to dart2jsPreselector
I am looking for a way that can support both web and ios/android. That is why I wanted isolated worker handle the delegation between web and ios/android. I think the js package will limit my application to web only. If I can generate a js file then I can let isolated worker delegate without having to do a web import.Rosebud
This does not solve the question. The function is added to the main scope and not the worker scope. It is not possible to run it from the worker.Rosebud
S
0

You can do this with dartscript.

file.dart

import 'package:js/js.dart';

@JS('doComputation')
String doComputation(String input) {
  return '$input output';
}

void main(){
  allowInterop(doComputation);
}

Now pass the dart file to dartscript while passing the function name as an option.

dartscript --func doComputation --out doComputation.js file.dart

doComputation.js

export function doComputation(input) {
  return input + ' output'
}

dartscript also supports CJS modules, or default exports. Just use the available options.

dartscript --func doComputation --out doComputation.cjs --module cjs --default file.dart

doComputation.cjs

module.exports = function doComputation(input) {
  return input + ' output'
}
Shinto answered 23/5 at 18:52 Comment(0)
C
-1

You can do this instead by using the package dart2js

one make a program for your main.dart dart2js where the function or command you wanted to make is there, then create a separate dart file what function you wanted to call, and it will fix your problem, it is a separate file but will only execute one function that you needed to do so and that is the separate file

Caddric answered 13/6, 2022 at 18:55 Comment(1)
Could you elaborate on this? I crated a separate dart project. Created a dart file where I call my function. Call this function in main.dart. And then run the dart2js command from my question. This gives a very similar output as before where I get a javascript program instead of a javascript function.Rosebud

© 2022 - 2024 — McMap. All rights reserved.