为 JavaScript 模块编写 scalajs Facade 时如何使用 JSImport

2024-03-16

我使用 JSImport 编写了一个外观,并且它有效。不幸的是,我通过反复试验找到了解决方案,并且我不完全理解为什么这个特定的解决方案有效,但我尝试过的其他解决方案却无效。

背景:我从一个使用 sbt 构建的工作项目开始,它是一个单页应用程序,使用 scala.js 实现客户端代码,使用 scala 和 Play 框架实现服务器端代码。 javascript 库与 Web jar 一起打包,并使用 sbt jsDependency 变量捆绑到客户端 js 文件中。我想实现一些需要升级库的新功能,然后需要升级一些仅以 npm 格式提供的 javascript 库。所以现在我使用 npmDependency 和 scalajs-bundler 插件包含客户端应用程序的所有 javascript 依赖项。这破坏了一些 scalajs 外观,导致了我的问题。

我将使用门面log4javascript http://log4javascript.org/docs/manual.html#jsonlayout作为这个问题的一个例子。

变量log4javascript是用于访问 api 其余部分的顶级对象。

当 js 库作为 Web jar 包含时,外观就是这样的log4javascript已实施:

@js.native
@js.annotation.JSGlobalScope
object Log4JavaScript extends js.Object {
  val log4javascript:Log4JavaScript = js.native
}

更改为 npm 后:


import scala.scalajs.js.annotation.JSImport.Namespace

@JSImport("log4javascript", Namespace)
@js.native
object Log4JavaScript extends js.Object {
  def resetConfiguration(): Unit = js.native
  def getLogger(name:js.UndefOr[String]): JSLogger = js.native
  ...
}

遵循 scala.jsdocs https://www.scala-js.org/doc/interoperability/facade-types.html为了编写导入模块,我期望对象名称(在本例中为 Log4JavaScript)必须与导出的符号名称匹配才能使绑定正常工作。然而,log4javascript.js 中的顶级符号是log4javascript。经过实验,似乎 scala 对象名称对于绑定没有影响。无论我如何命名 scala 顶级对象,它都会正确绑定。

有人可以解释一下,当使用“命名空间”参数进行 JSImport 时,scala 对象/类/def/val 名称与 javascript 模块中的名称之间存在什么关系(如果有)?

根据 scala.js 文档,我似乎应该能够提供 js 对象的实际名称(我也尝试过“Log4JavaScript”)

@JSImport("log4javascript", "log4javascript")
@js.native
object SomeOtherName extends js.Object {
  def resetConfiguration(): Unit = js.native
  def getLogger(name:js.UndefOr[String]): JSLogger = js.native
  ...
}

然而,这无法绑定。当我尝试访问任何成员函数时,我会收到运行时错误。

Log4JavaScript.resetConfiguration()

Uncaught TypeError: Cannot read property 'resetConfiguration' of undefined

有人可以解释为什么这不起作用吗?

log4javascript 还在范围内定义了一些类log4javascript。当 lib 作为 Web jar 包含时,定义如下所示:

@js.native
@JSGlobal("log4javascript.AjaxAppender")
class AjaxAppender(url:String) extends Appender {
  def addHeader(header:String, value:String):Unit = js.native
}

切换到 npm 后,我必须将类定义放入顶级对象中:

@js.native
trait Appender extends js.Object {
  ...
}

@JSImport("log4javascript", "log4javascript")
@js.native
object Log4JavaScript extends js.Object {
  ...
  class AjaxAppender(url: String) extends Appender {
    def addHeader(name: String, value: String): Unit = js.native 
  }
  ...
}

这似乎很合理,但从 scala.js 文档来看,似乎应该可以在顶级对象之外以这种方式定义它

@JSImport("log4javascript", "log4javascript.AjaxAppender")
@js.native
class AjaxAppender(url: String) extends Appender {
  def addHeader(name: String, value: String): Unit = js.native 
}

然而,这也无法绑定。有人可以解释一下上面定义类的正确方法吗?或者定义嵌套在Log4JavaScript反对唯一正确的方法吗?


有人可以解释一下,当使用“命名空间”参数进行 JSImport 时,scala 对象/类/def/val 名称与 javascript 模块中的名称之间存在什么关系(如果有)?

这在中进行了解释这部分 http://www.scala-js.org/doc/interoperability/facade-types.html#-imports-from-other-javascript-modulesScala.js 文档的一部分。定义外观的 Scala 对象的名称并不重要。重要的是参数@JSImport注解。第一个表示which从中导入的模块,第二个表示what导入。

在您的情况下,log4javascript 模块位于log4javascript.js文件,在log4javascript包目录。所以,你的第一个参数应该是:

@JSImport("log4javascript/log4javascript.js", ...)
object Log4JavaScript ...

然而,log4javascript 被定义为一个 npm 模块,其主文件 https://github.com/Ritzlgrmft/log4javascript/blob/8aade2bcfe4302058aa25a111890b129995d4c6b/package.json#L10指的是log4javascript.js文件。这意味着您可以只使用包目录名称:

@JSImport("log4javascript", ...)
object Log4JavaScript ...

(See 本文 https://www.freecodecamp.org/news/requiring-modules-in-node-js-everything-you-need-to-know-e7fbd119be8/有关 NodeJS 如何解析模块的更多信息)

第二个参数@JSImport注释指示要导入的内容。在你的情况下,你想导入整个模块,而不仅仅是它的成员,所以你想使用Namespace:

@JSImport("log4javascript", Namespace)
object Log4JavaScript ...

这对应于以下 EcmaScript 导入语句:

import * as Log4JavaScript from 'log4javascript'

请注意,虽然 Scala 对象名称 (Log4JavaScript,此处)并不重要,其成员的姓名确实很重要,如中所解释的这部分 http://www.scala-js.org/doc/interoperability/facade-types.html#javascript-fieldmethod-names-and-their-scala-counterpartScala.js 文档的一部分。

根据 scala.js 文档,我似乎应该能够提供 js 对象的实际名称(我也尝试过“Log4JavaScript”)

@JSImport("log4javascript", "log4javascript")
...

然而,这无法绑定。当我尝试访问任何成员函数时,我会收到运行时错误。

当您编写该内容时,您会尝试访问log4javascript的成员log4javascript模块。但该模块没有这样的成员。

应该可以在顶级对象之外以这种方式定义它

@JSImport("log4javascript", "log4javascript.AjaxAppender")
...

然而,这也无法绑定。

同样,这意味着“导入log4javascript.AjaxAppender成员来自log4javascriptmodule”,但该模块没有这样的成员。以下应该有效:

@JSImport("log4javascript", "AjaxAppender")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为 JavaScript 模块编写 scalajs Facade 时如何使用 JSImport 的相关文章

  • 如何在使用 Binding.scala 将元素加载到 dom 后执行一些 init

    dom def chart show Var Boolean if show bind
  • 无法让 uTest 查看我的测试

    我正在尝试让 uTest 与 ScalaJS 和 SBT 一起使用 SBT 正在编译文件 uTest 正在运行 但它只是忽略我的测试 尽我所能 我找不到我的代码和教程示例之间的任何区别 构建 sbt enablePlugins ScalaJ
  • Binding.scala:避免过多 dom 树更新的策略

    在我的项目中scala 适配器我显示通过网络套接字发送的日志条目 由于我无法控制发送的条目数量 因此我正在寻找一种策略来避免屏幕冻结 我创建了一个 ScalaFiddle 来模拟 https scalafiddle io sf kzr28t
  • 如何读取Scala.js中的资源文件?

    假设我有一个map csv文件位于同一级别 或其他一些 web 应用程序可访问的位置 index dev opt html e g key1 value1 key2 value2 keyN valueN 我想读取该 CSV 文件并最终得到一
  • 使用 scalajs 创建自定义 DOM 事件

    我找不到使用 scala js 创建自定义事件的方法 例如 使用 js 您可以创建如下所示的自定义事件 摘自此处 var event new CustomEvent build detail elem dataset time 但是 没有构
  • 调整大小之前传单地图无法正确显示

    我在 Binding scala 上使用带有 scalajs leaflet 外观的 Leaflet 并且地图初始化 显示不正确 为了重现这个问题 我准备了一个lihaoyi workbench页面类似于 scalajs leaflet 中
  • scala.js 与 jscala 有什么区别?

    有两个工具可以直接在 JavaScript 中编译 Scala 代码 Scala js http www scala js org and JScala https github com nau jscala 它们看起来都很棒 并且可以使用
  • 使用不透明类型(Char 和 Long)

    我正在尝试导出算法的 Scala 实现以在 JavaScript 中使用 我在用着 JSExport 该算法适用于 ScalaChar and Long值被标记为opaque in the 互操作性指南 http www scala js
  • 如何使用 scala.js 读取文本文件?

    基本上我想弄清楚我需要传递什么onload method def selectedFile e ReactEventI val reader new dom FileReader reader readAsText e currentTar
  • 如何导出共享案例类的属性

    我正在尝试在服务器和客户端之间共享案例类 我在两端都使用了 upickle 对象及其数据在两端都可以很好地使用 共享类 case class Foo var id Long var title Description 但是我需要在客户端导出
  • DOM 更新过多

    链接 https ccamel github io playground binding scala index html playground binding scala home https ccamel github io playg
  • 如何将现有的 Scala 库移植到 scalajs?

    我是 Scala js 新手 我想使用 Argonaut json 库 https github com argonaut io argonaut https github com argonaut io argonaut 它唯一的依赖项似
  • JSweet 能否有效地移植 Java 库以在交叉构建的 Scala.js 项目中使用?

    寻找使 Java 库可供 Scala js 的 JavaScript 和 JVM 端访问的方法交叉构建 https www scala js org doc project cross build html项目 请考虑以下实验 想象一下 S
  • 从 SJSIR “手动”构建 JS

    我需要在运行时从 sjsir 文件构建一个 js 文件来实现插件系统 这样就无法在编译时与我的其余编译一起完成 我曾经在 0 6 3 中使用以下代码实现相同的过程 但它似乎已被弃用 您建议使用什么算法来实现与 0 6 13 相同的操作 谢谢
  • 为 JavaScript 模块编写 scalajs Facade 时如何使用 JSImport

    我使用 JSImport 编写了一个外观 并且它有效 不幸的是 我通过反复试验找到了解决方案 并且我不完全理解为什么这个特定的解决方案有效 但我尝试过的其他解决方案却无效 背景 我从一个使用 sbt 构建的工作项目开始 它是一个单页应用程序
  • 如何从传递到 scalatags 的事件处理程序访问“this”元素?

    我正在尝试访问当前的文本 this 元素来自使用 scalatags 创建的事件处理程序 这是我尝试过的 val onChange e HTMLElement gt number e textContent toInt js ThisFun
  • 如何在 Nodejs 中实际运行 scalajs 代码?

    我正在开发一个后端聊天服务器 它目前是用混乱的回调 javascript 编写的 所以我正在考虑将其移植到 scalajs 我一直在浏览初学者指南 但我找不到如何将项目实际编译为可以使用节点运行的单个 JavaScript 文件 例如nod
  • scala-js 如何与 sbt-web 集成?

    我想用scala js https github com scala js scala js with sbt web https github com sbt sbt web以这样的方式 它可以被编译以生成添加到资产管道中的 JavaSc
  • 为什么不重新评估 Binding.scala 路由器?

    我正在尝试通过 Binding scala 为个人项目构建通用路由器 我定义了一个PageState trait sealed trait WhistState def text String def hash String def ren
  • 用于真实 Web 项目的 Scala-JS [已关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有人用过吗Scala JS在真实的网络项目中 但不仅仅适用于普通的JavaScript在隔离环境中替换 我想尽可能多地使用 Scala 我希望可

随机推荐

  • 查找 HTML5 表单用于验证的正则表达式

    一些 HTML5 输入元素接受pattern属性 它是用于表单验证的正则表达式 其他一些 HTML5 输入元素 例如 input type email自动进行验证 现在看来 跨浏览器处理验证的方式是不同的 给定一个特定的浏览器 比如 Chr
  • JSP/Servlet 中的倒计时器

    我正在使用 servlet jsp 开发在线考试 我需要在问题页面添加一个倒计时 hh mm ss 计时器 该计时器将结束考试并重定向到结果页面 除了计时器功能之外 我已经完成了所有其他功能 有人可以为此提供一些帮助吗 Thanks 您是否
  • 如何将本地数据存储数据导出到生产 Google App Engine 数据存储

    我想将本地数据存储数据导出到我的 google appengine 应用程序数据存储 有没有直接且简短的方法可以做到这一点 你可以阅读相关内容here http code google com appengine docs python t
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT
  • Angular 4 预定表单自动保存

    我正在尝试在 Angular 4 中实现表单数据自动保存 它应该像这样工作 用户更改表单中的某些数据 gt 调用对数据库的某些保存请求 我们假设这里启动了一些计时器 2 秒 在上一个保存请求之后的 2 秒内 所有更改都不会调用任何请求 以减
  • 为什么我的书呆子树有这些奇怪的字符

    尝试让 vim 设置顺利进行 我想让书呆子树发挥最佳状态 但是当我使用它时 它的每个部分前面都有这些字符 V 看起来像这样 V project V tools 我遇到了完全相同的问题 并且能够通过取消注释 UTF 8 并在 etc loca
  • 使用 HTML 和 CSS 扩展大括号

    有没有一种简单的方法可以模拟cases提供的环境amsmath在 LaTeX 中使用 HTML 和 CSS 例如 在 LaTeX 中 可以这样写 documentclass article usepackage amsmath begin
  • SQL Anywhere 11,JZ0C0:连接已关闭

    我开发基于 apache tomcat 6 0 26 apache cxf 2 2 7 spring 3 0 hibernate 3 3 和 sybase sqlanywhere 11 的 Web 服务 我使用 SYBASE jconn j
  • 使用回形针上传多个文件

    我在使用回形针上传多个文件时遇到问题 我的模型是这样的 slider has many imgarrays imgarrays has many imageobjects imageobjects have attachment as fo
  • Android 中的 WorkManager 多次执行 do Work()

    我正在使用 WorkManager 来安排一些任务 但问题是工作管理器在一次调用中多次执行这些任务 doWork 我在用 android arch work work runtime 1 0 0 alpha08 我尝试过使用 alpha07
  • 如何在 Google 云端硬盘中搜索子文件夹和子子文件夹?

    这是一个常见问题 场景是 folderA folderA1 folderA1a folderA2 folderA2a folderA2b 问题是如何列出根目录下所有文件夹中的所有文件folderA 编辑 2020 年 4 月 Google
  • 在 ASP.NET c# 中重定向到另一个页面之前显示 ClientScript 警报?

    我必须在这里解决一个问题 我正在开发一个系统 我不断地向用户显示消息 例如 我正在添加一个新客户端 我输入所有数据并按 保存 在 C 上我所做的就是完成所有保存过程 然后我使用 ClientScript RegisterStartupScr
  • 如何在没有 VS 6.0 的计算机上安装 Microsoft FlexGrid Control 6.0?

    我的 VB NET 应用程序使用 Microsoft Flex Grid Control 6 0 这是一个遗留应用程序 已通过 Visual Studio 转换向导从 VB6 移植 虽然我可以编译程序集 但由于某些类未注册 我收到了 COM
  • For 循环中的 Grunt 运行

    我是咕噜声的新手 我有一个适用于单个构建的 gruntfile 有几个目标链接在一起来完成该过程 问题是我需要使用变量数据创建几个不同的版本 我正在尝试弄清楚如何在我的 gruntfile 中执行此操作 今天 要进行构建 我只需要运行 gr
  • 让 `nosetests` 脚本按 Python 版本选择文件夹

    我曾经有过这个setup cfg file nosetests where test python toolbox 但现在我通过提供两个并行代码库来支持 Python 2 和 Python 3 其中一个位于source py2文件夹和其中一
  • 使用facet_wrap时,geom_bar中的条形有不需要的不同宽度

    我找不到以下问题的解决方案 我非常感谢一些帮助 以下代码使用facet 生成条形图 然而 由于 ggplot2 在某些组中具有 额外空间 即使我指定 0 1 或类似的宽度 它也会使条形变得更宽 我觉得这很烦人 因为它看起来很不专业 我希望所
  • 如何在 C++ 中正确返回数组(类成员)?

    我对 C 还很陌生 所以这可能是一个微不足道的问题 我的类有一个私有成员变量 它是一个数组 我需要返回该数组 但我不确定如何正确执行此操作 class X private double m Array 9 public double Get
  • 这段代码可以防止SQL注入吗?

    背景 我已签约分析现有数据提供者 并且我知道以下代码有错误 但为了指出它有多糟糕 我需要证明它容易受到 SQL 注入的影响 Question 什么 Key 参数可能会破坏PrepareString函数并允许我执行DROP陈述 代码片段 Pu
  • 如何访问网络文件?

    using namespace std ofstream myfile myfile open Z ABC TXT fails Z is a network drive myfile open C Temp ABC TXT OK myfil
  • 为 JavaScript 模块编写 scalajs Facade 时如何使用 JSImport

    我使用 JSImport 编写了一个外观 并且它有效 不幸的是 我通过反复试验找到了解决方案 并且我不完全理解为什么这个特定的解决方案有效 但我尝试过的其他解决方案却无效 背景 我从一个使用 sbt 构建的工作项目开始 它是一个单页应用程序