4

I've got the Funscript examples working. Now I'm trying to make something like a Funscript library which has functions (and hopefully classes!) that can be called from javascript code. But I can't see a way of accessing anything from the .js generated from Funscript.

In short, how do I get Javascript to call Funscript?

4

2 回答 2

3

Sorry but FunScript is not designed for this use case. It is designed for consuming code and data from various sources in a script rather than for exporting code as a library.

You will notice the code FunScript generates is quite ugly. We have improved it slightly recently but these changes are only available directly from the FunScript repository (at the time of writing). There is still a long way to go before it generates JavaScript that is nice to consume from other JavaScript based languages.

Improving the code generation is not a high priority task for the project right now. We don't want to commit to generating code in any particular style/format whilst we are actively adding large bits of new functionality. Also, it is hard to map some concepts from F# into consumable and performant JavaScript. For example:

  • Generic types, methods and functions
  • Generic type constraints (on things like equality and comparison)
  • Reflection

To illustrate the generic case, suppose in F# you have a generic function that makes use of a comparison constraint to sort an array of instances of the generic type. First, you use it with a primitive numeric type like int. Second, you use it with a record type. If the same JavaScript code is generated for both situations and the comparison is achieved by calling some method say Compare(...) on the objects this results in very poor performance for the numeric case. To achieve better performance, some specialisation of the generated code is needed. Here the comparison of F# types that map to built in JavaScript types (like number and string) can be inlined. This gives much better performance, however, you now have multiple JavaScript versions of the same F# function. There isn't a clear way to present this generated code in an easy to consume fashion.

In summary, the FunScript design makes some trade offs that prioritise things like support for generics, performance and reflection over things like code generation. You may want to look at WebSharper instead. It may support this use case.

于 2013-10-08T23:17:11.030 回答
2

You can expose functions by putting them on the window object. For example:

[<ReflectedDefinition>]
module Program

open FunScript
open FSharp.Data
open System.IO

module Foo =
  let SayHello name = Globals.window.alert ("Hello, " + name)

[<JSEmitInlineAttribute("window.SayHello = {0};")>]
let expose(f : string -> unit) : unit = failwith "never"

// Create a function that will be compiled into JavaScript...
let main () =
  expose(Foo.SayHello)

You can then access them from javascript:

window.SayHello("Ray");

Or, in fact, simply:

SayHello("Ray");
于 2014-01-11T11:37:28.287 回答