2017-04-25 49 views
0

問題:想回到()=>要求(路徑)從宏觀如何從宏scala.js返回需要調用

def gql(args: js.Any*): js.Function0[js.Any] = macro rqlMacroImpl 
//impl 
val generatedFilePath = ... 
    c.Expr[js.Function0[js.Any]](q""" 
     { 
      import scala.scalajs.js 
         import scala.scalajs.js.annotation.JSImport 

      val func:js.Function0[js.Any] =() => require($generatedFilePath)// I want to return require(...) 
      func 
     } 
    """) 

所以嘗試遠

//impl 
    val generatedFilePath = ... 
     c.Expr[js.Function0[js.Any]](q""" 
      { 
       import scala.scalajs.js 
          import scala.scalajs.js.annotation.JSImport 
       @js.native 
       @JSImport($generatedFilePath,JSImport.Default) 
       object GQlImport extends js.Object 
       val func:js.Function0[js.Any] =() => GQlImport 
       func 
      } 
     """) 

失敗Local native object/classes not allowed

解決方法:

使用js.Dynamic.global.require(path)和SBT任務取代$g.require(require(

任何更好的選擇..?

回答

1

你不能這樣做,因爲@JSImport必須是頂層的,只能在不是頂層的地方調用宏。

@JSImport必須是頂級的原因是它確實不是而是在語義上對應於require。相反,它對應於ES2015中的import。當他們瞄準CommonJS模塊時,他們將desugar轉換爲require,但這是一種特殊情況。 require的動態使用不能根據ES2015中的import編寫,因此也不能根據@JSImport編寫。

現在您需要將$g.require調整爲require的原因是另一個問題。過去的情況是,這只是Node.js以非規範兼容方式劫持JavaScript,而Scala.js不允許您訪問它。現在事實證明,ES2015類型使得這個特殊的require東西有效,所以最終你將能夠在Scala.js中原生地訪問它,通過https://github.com/scala-js/scala-js/issues/2800