2017-01-16 6 views
0

tl; dr : scalajs-java-time과 같은 라이브러리가 종속성을 대체하는 방법은 무엇입니까?Scala.js 플랫폼 의존 메소드 구현 (또는 종속성 삽입)

object Example { 
    def method(...) = { ... dependsOnPlatform ... } 
    val dependsOnPlatform = ??? 
} 

이 일의 순진 방법은 다음과 같습니다 :

val dependsOnPlatform = if(onJS) jsImplementation else jvmImplementaion 

문제는 공유 코드에서

:

나는 Scala.js이 의존성 주입에 달렸다 Scala.js 클래스에 의존하기 때문에 종종 JVM을 위해 jsImplementation을 컴파일 할 수 없습니다. 리플렉션을 사용하거나 자바 클래스를 참조하는 경우 jvmImplementaionfastOptJS을 완료하지 못할 수도 있습니다.

object Example은 정적이어야하며 생성자 삽입을 사용할 수 없습니다.

리플렉션을 사용하면 문제를 쉽게 해결할 수 있지만 다시 Scala.js에서는 허용되지 않습니다.
부작용으로 해결 될 수도 있지만 개체가 정적이어서 취약합니다.
종속성은 method의 암시 적 매개 변수 일 수 있지만 추가 가져 오기가 필요합니다.
그리고 이것은 매크로가 빌드 프로세스를 복잡하게하지 않고 해결할 수있는 문제가 아닙니다.

답변

2

권장 해결책은 js/src/에서 jvm/src/보다 다르게 구현 된 최상위 수준 개체를 사용하는 것이지만 동일한 인터페이스를 둘 다 노출합니다. 그 객체의 API는 일반적으로 shared/src/ 코드에서 사용할 수 있습니다. 이 개체는 일반적으로 Platform이라고하며 package-private로 설정됩니다.

js/src/.../Platform.scala

package foo 

private[foo] object Platform { 
    def dependsOnPlatform(...) = { 
    jsImplementation 
    } 
} 

jvm/src/.../Platform.scala

package foo 

private[foo] object Platform { 
    def dependsOnPlatform(...) = { 
    jvmImplementation 
    } 
} 

shared/src/.../Platform.scala

package foo 

object Example { 
    def method(...) = { 
    ... 
    Platform.dependsOnPlatform(...) 
    ... 
    } 
} 

설명 된 바와 같이, 해킹이나 된 .java 소스 파일을 작성하는 "그림자"못생긴을 사용할 필요가 없습니다 @ acdenh의 대답.

+0

그래, 난 그냥 그림자 프로젝트가 잘못 CrossProject 빌드를 디버깅하는 동안 알게되었습니다. 내가 놓친 것은 공유 코드가 별도로 컴파일 할 필요가 없다는 것입니다. 이 CrossProject 시스템에 대해 혼란 스러울 정도의 비난을 많이합니다. 마지막으로 소스 코드를 읽었을 때 설치가 얼마나 단순한 지 분명 해졌다. – acdenh

0

올바른 해결책은 Java 클래스를 만들고 Scala.js 클래스로 "섀도 잉"하는 것입니다. 프로젝트의 Scala.js 부분에 다음

val dependsOnPlatform = new Injection 

class InjectionForJVM { ... } //InjectionForJVM.scala 

public class Injection extends InjectionForJVM { } //Injection.java 

:

공유 코드에서

class Injection { ... } //Injection.scala 

Injection 클래스 모두 같은 패키지에 있어야하고 동일한 인터페이스를 가지고 .
Injection.java이 제대로 컴파일되지 않을 수 있으므로 InjectionForJVM.scala을 임의의 개체 또는 클래스 안에 넣지 마십시오. InjectionForJVM.scala은 반사 및 Java 메소드를 모두 사용할 수 있습니다. 클래스에 도달 할 수 없으므로 fastOptJS입니다. 또한 Injection.java을 Java로 직접 구현할 수도 있지만 누가 그럴 수 있겠습니까?

(Injection.java는 어떤 경우에 Scala.js 존재하지 않기 때문에,이 정말 그림자되지 않습니다. JVM을에 수업의 실제 음영이 가능하지만 일반적으로 권장하지 않습니다. 정확히 말하면)