Как экспортируются интерфейсы в Funscript
У меня работают примеры Funscript. Теперь я пытаюсь создать что-то вроде библиотеки Funscript, в которой есть функции (и, надеюсь, классы!), Которые можно вызывать из кода javascript. Но я не вижу способа получить доступ к чему-либо из.js, сгенерированного из Funscript.
Короче, как мне заставить Javascript вызывать Funscript?
2 ответа
Извините, но FunScript не предназначен для этого варианта использования. Он предназначен для использования кода и данных из различных источников в сценарии, а не для экспорта кода в виде библиотеки.
Вы заметите, что код, который генерирует FunScript, довольно уродлив. Мы немного улучшили его в последнее время, но эти изменения доступны только непосредственно из репозитория FunScript (на момент написания). Еще предстоит пройти долгий путь, прежде чем он сгенерирует JavaScript, который приятно использовать из других языков на основе JavaScript.
Улучшение генерации кода сейчас не является приоритетной задачей для проекта. Мы не хотим создавать код в каком-либо определенном стиле / формате, в то время как мы активно добавляем большие биты новой функциональности. Кроме того, трудно сопоставить некоторые концепции из F# с потребляемым и производительным JavaScript. Например:
- Общие типы, методы и функции
- Общие ограничения типов (на такие вещи, как равенство и сравнение)
- отражение
Чтобы проиллюстрировать универсальный случай, предположим, что в F# у вас есть универсальная функция, которая использует ограничение сравнения для сортировки массива экземпляров универсального типа. Во-первых, вы используете его с примитивным числовым типом, таким как int. Во-вторых, вы используете его с типом записи. Если один и тот же код JavaScript генерируется для обеих ситуаций, и сравнение выполняется путем вызова некоторого метода, скажем Compare(...)
на объектах это приводит к очень низкой производительности для числового случая. Для достижения лучшей производительности требуется некоторая специализация сгенерированного кода. Здесь может быть встроено сравнение типов F#, которые отображаются на встроенные типы JavaScript (такие как число и строка). Это дает гораздо лучшую производительность, однако теперь у вас есть несколько версий JavaScript одной и той же функции F#. Нет четкого способа представить этот сгенерированный код в удобном для использования виде.
Таким образом, дизайн FunScript делает некоторые компромиссы, которые отдают приоритет таким вещам, как поддержка обобщений, производительность и отражение над такими вещами, как генерация кода. Вы можете вместо этого взглянуть на WebSharper. Это может поддержать этот вариант использования.
Вы можете выставлять функции, помещая их в объект окна. Например:
[<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)
Затем вы можете получить к ним доступ из JavaScript:
window.SayHello("Ray");
Или, на самом деле, просто:
SayHello("Ray");