#scala.js #playscalajs
#scala.js #воспроизводит scalajs
Вопрос:
Я обновил свой проект Play ScalaJS с ScalaJS 0.6.32 до 1.4.0 несколько недель назад. В разработке все работает нормально. Сегодня я попытался развернуть его и, таким образом fullLinkJS
, впервые выполнил. Это породило ряд ошибок:
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
...
Я просмотрел около дюжины строк, на которые ссылаются ссылки в исходном коде. Большинство из них относятся либо к маршруту воспроизведения, либо к вызову url
метода. Остальные из них связаны с вызовом jQuery.
Проект имеет кросс-платформенный подпроект. Это делает fulllink JS просто отлично. Существует также клиентский проект ScalaJS. Вот где происходят ошибки.
Я использую ScalaJS 1.4.0 и играю 2.6.25.
Предложения о том, как действовать?
Позже, после прочтения ответа от @sjrd
Пример кода-нарушителя:
private val wapp = routes.oat.wapp.controllers.BMailCtrl
...
window.location.href = wapp.edit(emailId).url // this is the line flagged with the error
window
определяется org.scalajs.dom
как a js.Dynamic
.
routes
определяется в моем коде как val routes: js.Dynamic = global.jsRoutes
. Аннотация js.Dynamic
типа — это то, что выводится IntelliJ.
Ага! global
определяется scala.scalajs.js
как расширяющийся scala.Dynamic
. Но я считаю jsRoutes
, что их следует интерпретировать как js.Dynamic
. Это маршруты, созданные игровым сервером.
Похоже, мне нужно изменить способ доступа к этим ребятам. Исследуя, в частности, Scala.js Глобалскоп.
Еще позже — исправление
Я записываю то, что я сделал здесь, чтобы я мог пометить ответ sjrd как «ответ».
Как уже отмечалось, большинство моих ошибок проверки IR были в строках формы
window.location.href = wapp.edit(emailId).url
href
имеет тип String
и url
является js.Dynamic
, но выдает строку. Я думаю, в этом и заключается проблема.
Исправление, однако, было простым: добавить toString
:
window.location.href = wapp.edit(emailId).url.toString
Все остальные ошибки проверки IR были вариантами этого с аналогичным исправлением.
Ответ №1:
Ошибки, которые вы видите, являются «ошибками проверки IR». Они означают, что в .sjsir
файлах, созданных компилятором, есть несоответствия. По умолчанию они проверяются только для fullOpt
задач, поэтому вы их раньше не видели. Однако это не означает, что IR больше действителен для fastOpt
(это тот же IR!), Поэтому ошибка всегда была там (скрытая), но появляется только сейчас. Наличие ошибок проверки IR означает, что оптимизатор или просто генератор кода JavaScript могут выдавать бессмысленные результаты.
(Ошибки проверки IR также похожи на VerifyError
s в JVM.
Вообще говоря, существует 3 источника ошибок IR-проверки:
- Использование двоичных несовместимых версий транзитивных библиотек может привести к ошибкам проверки IR в некоторых редких случаях, даже если ошибка связывания не возникает.
- Ошибки в Scala.js основная цепочка инструментов (компилятор, компоновщик)
- Определенная известная (и несколько преднамеренная) проблема с ошибками в Scala.js введите system: js.Dynamic <: scala.Динамические причины неисправности в IR.
С чем вы столкнулись, так это с последней проблемой. Это довольно редко. В принципе, это происходит, если вы присваиваете (через =
или передавая аргумент функции и т.д.) значение типа js.Dynamic
значению типа. scala.Dynamic
Например:
val jsDyn = js.Dynamic.literal(foo = "bar")
val scalaDyn: scala.Dynamic = jsDyn
Средство проверки типов принимает этот фрагмент, потому что во время компиляции js.Dynamic
он расширяется scala.Dynamic
. Это необходимо для js.Dynamic
того, чтобы в первую очередь раскрыть его динамизм, поэтому мы не можем это изменить. Однако во время ссылки и выполнения js.Dynamic
это тип JavaScript (поскольку он расширяется js.Any
) и scala.Dynamic
является типом Scala, а типы JavaScript никогда не являются подтипами типов Scala.
Итак, что это оставляет вас?
Посмотрите на код, на который указывают сообщения об ошибках. Вам нужно будет определить место, где a js.Dynamic
(или любой другой тип JS, который расширяется scala.Dynamic
, но js.Dynamic
обычно является единственным подобным) присваивается a scala.Dynamic
.
Крайне редко писать scala.Dynamic
(или просто Dynamic
) как тип вручную (и это, вероятно, всегда ошибка), но может случиться так, что это выводится компилятором, например, если у вас есть две ветви if / else, которые возвращают два разных подтипа scala.Dynamic
.
Это все, что я могу сказать, не видя проблемный фрагмент кода.
Комментарии:
1. Спасибо за подробное объяснение, @sjrd. Является ли это новым поведением с ScalaJS 1.x? Я не сталкивался с этим с серией 0.6.
2. С точки зрения оскорбительного кода многие из них выглядят так: private val wapp = routes.oat.wapp.controllers. Окно BMailCtrl. Расположение. href = wapp.edit(emailId).url // это окно, помеченное строкой, определено в org.scalajs.dom как
js.Dynamic
. маршруты определены в моем коде как `val routes: js.Dynamic = global.jsRoutes. The
js.Dynamic` — это то, что выводится IntelliJ.3. Тот факт, что целостность IR проверяется по умолчанию в fullOpt, является новым в 1.x. Но базовые правила валидности не новы, и поэтому скрытая проблема уже существовала в 0.6.x.
4. Попробуйте вставить явные
js.Dynamic
типы в различные соответствующие части кода, чтобы сузить круг источниковscala.Dynamic
.