[英]ScalaJS fullLinkJS errors
I upgraded my Play+ScalaJS project from ScalaJS 0.6.32 to 1.4.0 several weeks ago.几周前,我将我的 Play+ScalaJS 项目从 ScalaJS 0.6.32 升级到了 1.4.0。 All has been working fine in development.一切都在开发中运行良好。 Today I tried to deploy it and thus executed fullLinkJS
for the first time.今天我尝试部署它,因此第一次执行了fullLinkJS
。 It generated a number of errors:它产生了许多错误:
sbt:browser> fullLinkJS
[info] Full optimizing /Users/bwbecker/oat/src/oat3/_browser/target/scala-2.12/browser-opt
[error] c91662c1ae832d6a8493/oat/browser/views/bulkmail/BMailCreateView.scala(125:43:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/components/filteredTable/FilteredBMailTable.scala(81:53:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/models/Autocomplete.scala(156:18:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/virtualq/QueueAddEditView.scala(90:52:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/bulkmail/edit/BMailSendView.scala(273:62:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
[error] c91662c1ae832d6a8493/oat/browser/views/bulkmail/TemplateListView.scala(42:64:Apply): scala.Dynamic expected but any found for tree of type org.scalajs.ir.Trees$JSSelect
...
I've looked at about a dozen of the referenced lines in the source code.我查看了源代码中大约十几个引用的行。 Most of them refer to either a Play route or invoke the url
method.它们中的大多数都指的是播放路线或调用url
方法。 The rest of them involve a call to jQuery.其中的 rest 涉及对 jQuery 的调用。
The project has a cross-platform subproject.该项目有一个跨平台的子项目。 That one does the fullLinkJS just fine.那个做fullLinkJS就好了。 There's also a client-specific ScalaJS project.还有一个特定于客户端的 ScalaJS 项目。 That's where the errors are happening.这就是错误发生的地方。
I'm using ScalaJS 1.4.0 and Play 2.6.25.我正在使用 ScalaJS 1.4.0 和 Play 2.6.25。
Suggestions on how to procede?关于如何进行的建议?
A sample of the offending code:有问题的代码示例:
private val wapp = routes.oat.wapp.controllers.BMailCtrl
...
window.location.href = wapp.edit(emailId).url // this is the line flagged with the error
window
is defined in org.scalajs.dom
as a js.Dynamic
. window
在org.scalajs.dom
中定义为js.Dynamic
。
routes
is defined in my code as val routes: js.Dynamic = global.jsRoutes
. routes
在我的代码中定义为val routes: js.Dynamic = global.jsRoutes
。 The js.Dynamic
type annotation is what is inferred by IntelliJ. js.Dynamic
类型注释是 IntelliJ 推断的。
Aha!啊哈! global
is defined in scala.scalajs.js
as extending scala.Dynamic
. global
在scala.scalajs.js
中定义为扩展scala.Dynamic
。 But I believe the jsRoutes
should be interpreted as a js.Dynamic
.但我相信jsRoutes
应该被解释为js.Dynamic
。 It's the routes produced by the Play server.它是 Play 服务器生成的路由。
It looks like I need to change how I access those guys.看来我需要改变访问这些人的方式。 Researching, particularly,Scala.js GlobalScope .特别是研究Scala.js GlobalScope 。
I'm recording what I did here so I can mark sjrd's answer as "the answer".我正在记录我在这里所做的事情,以便我可以将 sjrd 的答案标记为“答案”。
As noted, most of my IR validation errors were on lines of the form如前所述,我的大部分 IR 验证错误都在表格的行上
window.location.href = wapp.edit(emailId).url
href
has a type of String
and url
is js.Dynamic
but produces a string. href
的类型为String
, url
是js.Dynamic
但会生成一个字符串。 I think therein lies the problem.我认为这就是问题所在。
The fix, however, was simple: add toString
:然而,修复很简单:添加toString
:
window.location.href = wapp.edit(emailId).url.toString
All the other IR validation errors were variants of this with a similar fix.所有其他 IR 验证错误都是具有类似修复的变体。
The errors you see are "IR checking errors".您看到的错误是“IR 检查错误”。 They mean that there are inconsistencies in the .sjsir
files that are produced by the compiler.它们意味着编译器生成的.sjsir
文件中存在不一致。 By default, they are only checked for fullOpt
tasks, which is why you have not seen them before.默认情况下,它们只检查fullOpt
任务,这就是你以前没有见过它们的原因。 However, that does not mean the IR is any more valid for fastOpt
(it's the same IR,), so the error was always there (latent).但是,这并不意味着 IR 对fastOpt
更有效(它是相同的 IR),所以错误总是存在(潜在的)。 but only surfaces now, Having IR checking errors means that the optimizer, or simply the JavaScript code generator.但现在只是表面,有 IR 检查错误意味着优化器,或者只是 JavaScript 代码生成器。 can produce nonsensical results.可以产生无意义的结果。
(IR checking errors are also similar to VerifyError
s on the JVM. (IR 检查错误也类似于 JVM 上的VerifyError
。
Broadly speaking, there are 3 sources of IR checking errors:一般来说,IR 检查错误有 3 个来源:
What you are experiencing is the latter issue.您遇到的是后一个问题。 It is quite rare.这是相当罕见的。 Basically, it happens if you assign (through =
or passing a function argument, etc.) a value of type js.Dynamic
to a value of type scala.Dynamic
.基本上,如果您将 js.Dynamic 类型的值分配给js.Dynamic
类型的值(通过=
或传递scala.Dynamic
参数等),就会发生这种情况。 For example:例如:
val jsDyn = js.Dynamic.literal(foo = "bar")
val scalaDyn: scala.Dynamic = jsDyn
The type checker accepts that snippet because, at compile-time, js.Dynamic
extends scala.Dynamic
.类型检查器接受该片段,因为在编译时, js.Dynamic
扩展scala.Dynamic
。 This is necessary for js.Dynamic
to expose its dynamism in the first place, so we cannot change that.这是js.Dynamic
首先暴露其活力所必需的,因此我们无法更改它。 However, at link- and run-time, js.Dynamic
is a JavaScript type (because it extends js.Any
) and scala.Dynamic
is a Scala type, and JavaScript types are never subtypes of Scala types. However, at link- and run-time, js.Dynamic
is a JavaScript type (because it extends js.Any
) and scala.Dynamic
is a Scala type, and JavaScript types are never subtypes of Scala types.
So where does that leave you?那么,这让你何去何从?
Look at the code pointed by the error messages.查看错误消息指向的代码。 You will need to identify a place where a js.Dynamic
(or any other JS type that extends scala.Dynamic
, but js.Dynamic
is typically the only one like that) is assigned to a scala.Dynamic
.您需要确定一个js.Dynamic
(或任何其他扩展scala.Dynamic
的 JS 类型,但js.Dynamic
通常是唯一这样的)分配给scala.Dynamic
的位置。
It is extremely rare to write scala.Dynamic
(or just Dynamic
) as a type by hand (and doing so is probably always a mistake), but it could be the case that it is inferred by the compiler, for example if you have two branches of an if/else that return two different subtypes of scala.Dynamic
.手动编写scala.Dynamic
(或只是Dynamic
)作为一种类型是极其罕见的(这样做可能总是一个错误),但它可能是由编译器推断出来的,例如,如果你有两个if/else 的分支,返回scala.Dynamic
的两个不同子类型。
This is all I can say without seeing the problematic code snippet.在没有看到有问题的代码片段的情况下,我只能这么说。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.