如何 return 从 scala.js 中的宏调用 require
how to return a require call from macro in scala.js
问题: 想要 return () => require(path) from macro
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(
有更好的选择.. ?
不能那样做,因为@JSImport
必须是顶层的,宏只能在非顶层的地方调用。
@JSImport
必须是顶级的原因是它 在语义上 不对应 require
。相反,它对应于 ES2015 中的 import
。当以 CommonJS 模块为目标时,他们 将 脱糖为 require
,但这是一种特殊情况。 require
的动态使用不能用 ES2015 中的 import
来写,因此也不能用 @JSImport
来写。
现在您必须将 $g.require
调整为 require
的原因是另一个问题。过去的情况是,这只是 Node.js 以不符合规范的方式劫持 JavaScript,并且 Scala.js 不允许您访问它。现在事实证明,ES2015 使那个特殊的 require
东西变得有效,所以最终你将能够通过 https://github.com/scala-js/scala-js/issues/2800
在 Scala.js 中本地访问它
问题: 想要 return () => require(path) from macro
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(
有更好的选择.. ?
不能那样做,因为@JSImport
必须是顶层的,宏只能在非顶层的地方调用。
@JSImport
必须是顶级的原因是它 在语义上 不对应 require
。相反,它对应于 ES2015 中的 import
。当以 CommonJS 模块为目标时,他们 将 脱糖为 require
,但这是一种特殊情况。 require
的动态使用不能用 ES2015 中的 import
来写,因此也不能用 @JSImport
来写。
现在您必须将 $g.require
调整为 require
的原因是另一个问题。过去的情况是,这只是 Node.js 以不符合规范的方式劫持 JavaScript,并且 Scala.js 不允许您访问它。现在事实证明,ES2015 使那个特殊的 require
东西变得有效,所以最终你将能够通过 https://github.com/scala-js/scala-js/issues/2800