vmunier / sbt-web-scalajs Goto Github PK
View Code? Open in Web Editor NEWSBT plugin to use Scala.js along with any sbt-web server.
License: Apache License 2.0
SBT plugin to use Scala.js along with any sbt-web server.
License: Apache License 2.0
Does this happen to anyone else? A problem for us for years, and I thought maybe we were doing something wrong. The example here is quite helpful though and seems to be what we are doing.
I would like to know if there is any way to have IntelliJ recognize method calls from within the Play templates. I was able to get the method to run and work as expected but I would like to have IntelliJ autocomplete method calls for me. Is there anyway to set this up? All I get is an unresolved function or method.
NOTE: Everything work fine its an IntelliJ issue. The plugin is awesome.
This is how I am calling the method: onclick="example.ScalaJSExample().addClickedMessage
And this is the playscalajs call in the template. @playscalajs.html.selectScript("client","/assets")
Again...it's a small issue, it's just that the yellow underline is bugging me :)
Hello,
Using the current version sbt-web-scalajs 1.1.0 (works perfectly with 1.011)
I get this message from SBT after it tries to extract the project structure:
/home/gilbert/.jdks/openjdk-14.0.1/bin/java -Djline.terminal=jline.UnsupportedTerminal -Dsbt.log.noformat=true -Dfile.encoding=UTF-8 -Didea.managed=true -Dfile.encoding=UTF-8 -jar /home/gilbert/.var/app/com.jetbrains.IntelliJ-IDEA-Community/data/JetBrains/IdeaIC2020.1/Scala/launcher/sbt-launch.jar
Extracting structure failed
My "Build.sbt" is as follows:
lazy val server = (project in file("server"))
.settings(commonSettings)
.settings(
scalaJSProjects := Seq(client),
pipelineStages in Assets := Seq(scalaJSPipeline),
pipelineStages := Seq(digest, gzip),
// triggers scalaJSPipeline when using compile or continuous compilation
compile in Compile := ((compile in Compile) dependsOn scalaJSPipeline).value,
libraryDependencies ++= Seq(
"com.vmunier" %% "scalajs-scripts" % "1.1.4",
guice,
specs2 % Test
)
)
.enablePlugins(PlayScala)
.enablePlugins(WebScalaJSBundlerPlugin)
.enablePlugins(SbtWeb)
.dependsOn(sharedJvm)
lazy val client = (project in file("client"))
.settings(commonSettings)
.settings(
scalaJSUseMainModuleInitializer := true,
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % "1.0.0"
)
)
.settings(
stFlavour := Flavour.Slinky,
useYarn := true
)
.settings(
Compile / npmDependencies ++= Seq(
"js-year-calendar" -> "1.0.2",
"rc-year-calendar" -> "1.0.2",
"react" -> "16.13.1",
"react-dom" -> "16.13.1"
)
)
.enablePlugins(ScalaJSPlugin, ScalaJSWeb, ScalaJSBundlerPlugin, ScalablyTypedConverterPlugin)
.dependsOn(sharedJs)
lazy val shared = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.in(file("shared"))
.settings(commonSettings)
.jsConfigure(_.enablePlugins(ScalaJSWeb))
lazy val sharedJvm = shared.jvm
lazy val sharedJs = shared.js
lazy val commonSettings = Seq(
scalaVersion := "2.13.2",
scalacOptions += "-Ymacro-annotations",
organization := "com.gb"
)
onLoad in Global := (onLoad in Global).value.andThen(state => "project server" :: state)
My plugins.sbt is as follows:
// Comment to get more information during initialization
logLevel := Level.Warn
// Resolvers
resolvers += "Typesafe repository" at "https://repo.typesafe.com/typesafe/releases/"
resolvers += Resolver.bintrayRepo("oyvindberg", "converter")
resolvers += Resolver.sonatypeRepo("releases")
// Sbt plugins
// Use Scala.js v1.x
//addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.0.11")
addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.1.0")
//addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.1.06")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.1.1")
//addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.1.1")
Any help would be appreciated.
Many thanks!
Currently I get the following output:
schmitch@SHANGHAI:~/projects/schmitch/play/play-with-scalajs-example$ sbt web-assets:assets
[info] Loading global plugins from /Users/schmitch/.sbt/0.13/plugins
[info] Updating {file:/Users/schmitch/.sbt/0.13/plugins/}global-plugins...
[info] Resolving org.scala-sbt.ivy#ivy;2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Loading project definition from /Users/schmitch/projects/schmitch/play/play-with-scalajs-example/project
[info] Set current project to play-with-scalajs-example (in build file:/Users/schmitch/projects/schmitch/play/play-with-scalajs-example/)
[info] Set current project to server (in build file:/Users/schmitch/projects/schmitch/play/play-with-scalajs-example/)
[success] Total time: 0 s, completed 05.09.2016 23:05:11
[info] Updating {file:/Users/schmitch/projects/schmitch/play/play-with-scalajs-example/}sharedJVM...
[info] Resolving org.scala-lang#scala-reflect;2.11.8 ...
[info] Updating {file:/Users/schmitch/projects/schmitch/play/play-with-scalajs-example/}sharedJS...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-library;2.11.8 ...
[info] Updating {file:/Users/schmitch/projects/schmitch/play/play-with-scalajs-example/}server...
[info] Resolving org.eclipse.jetty#jetty-continuation;8.1.16.v20140903 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-library;2.11.8 ...
[info] Updating {file:/Users/schmitch/projects/schmitch/play/play-with-scalajs-example/}client...
[info] Resolving com.fasterxml.jackson.datatype#jackson-datatype-jsr310;2.7.6 ..[info] Resolving org.eclipse.jetty.websocket#websocket-client;9.2.15.v20160210 .[info] Resolving org.eclipse.jetty.websocket#websocket-common;9.2.15.v20160210 .[info] Resolving jline#jline;2.12.1 ...
[info] downloading https://repo1.maven.org/maven2/com/vmunier/scalajs-scripts_2.11/1.0.0/scalajs-scripts_2.11-1.0.0.jar ...
[info] [SUCCESSFUL ] com.vmunier#scalajs-scripts_2.11;1.0.0!scalajs-scripts_2.11.jar (154ms)
[info] Done updating.
[info] Resolving org.scala-lang.modules#scala-parser-combinators_2.11;1.0.4 ...
[info] Compiling 1 Scala source to /Users/schmitch/projects/schmitch/play/play-with-scalajs-example/shared/.jvm/target/scala-2.11/classes...
[info] Resolving org.eclipse.jetty#jetty-continuation;8.1.16.v20140903 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/schmitch/projects/schmitch/play/play-with-scalajs-example/shared/.js/target/scala-2.11/classes...
[info] Compiling 1 Scala source to /Users/schmitch/projects/schmitch/play/play-with-scalajs-example/client/target/scala-2.11/classes...
[info] Full optimizing /Users/schmitch/projects/schmitch/play/play-with-scalajs-example/client/target/scala-2.11/client-opt.js
[info] Closure: 0 error(s), 0 warning(s)
[success] Total time: 9 s, completed 05.09.2016 23:05:19
however on development it should definitly say "fast-opt"
Project: https://github.com/vmunier/play-with-scalajs-example
it also creates the client-opt.js only.
Btw: addSbtPlugin("com.vmunier" % "sbt-play-scalajs" % "0.3.1")
worked correctly.
IntelliJ has a built-in run task for Play. However, I cannot run this task with ScalaJS, because the task looks for a project with the name root
. Do you just run with activator run
or use the Play task of IntelliJ?
With sbt 1.1.1 I was running a Play project using the task server / run
. The executedCommandKey
task will stop parsing the task when it encounters whitespace and so in this case executedCommandKey
is "server"
and not "run"
. The consequence is that isDevMode
will be false
instead of true
.
Sorry if this is another stupid question but is it possible to exclude the sourcemap files that are generated? I'm using play-scalajs-sourcemaps which is nice because it hides them in prod but upon further investigation it looks like the .map files generated from scalajs are still present and accessible when the server is running.
I'm pretty new to the whole scalajs thing so it's probably just a config i'm not seeing.
If I use server/run
(instead of, say, ;project server; run
) the command is not recognized as a “dev” command. Same with re-start
.
I'm not sure how you enable plugins on the play submodule so I can enable SbtWeb and turn on some pipelines (digest, gzip, etc). I've tried adding it onto both the PlayScalaJS project and the one referenced from playScalaJs.jvm. Is this something that just isn't possible or am I just doing something really stupid?
scalaJSDev
is currently started when the user executes one of the devCommands, which are compile
, run
and re-start
.
scalaJSDev
should also be started when the user executes a devCommand with arguments, e.g. run 9001
.
Related issue: #25
Hi,
I think it is currently not possible to use sbt-web-scalajs with single-project build. What I mean, is to have scalajs sources in our sbt-web project. Currently we need to have at least two projects: "sbt-web one" and "scalajs one".
If I'm wrong or there is a good reason for such behaviour please tell me!
Thanks
I think I might want to serve multiple different js applications from the same play backend, but it is not clear how to setup the build file when using the cross build plugin.
I'm in the process of updating dependencies for my play+scala.js project and ran into an issue with sbt-web-scalajs. I updated from v 1.1.0 to 1.3.0 and my compiles started failing:
...
[warn] 15 warnings found
[info] Fast optimizing /Users/bwbecker/oat/src/oat3/_browser/target/scala-2.13/browser-fastopt
[info] LESS compiling on 5 source(s)
[info] LESS compiling on 1 source(s)
[error] stack trace is suppressed; run last wapp / Web-assets / less for the full output
[error] stack trace is suppressed; run last wsvc / Web-assets / less for the full output
[error] (wapp / Web-assets / less) java.lang.NoSuchMethodError: 'java.lang.Object com.typesafe.sbt.web.SbtWeb$.withActorRefFactory(sbt.State, java.lang.String, scala.Function1)'
[error] (wsvc / Web-assets / less) java.lang.NoSuchMethodError: 'java.lang.Object com.typesafe.sbt.web.SbtWeb$.withActorRefFactory(sbt.State, java.lang.String, scala.Function1)'
[error] Total time: 35 s, completed Jan. 25, 2024, 12:14:26 p.m.
[oat] $ last wsvc / Web-assets / less
[error] Expected configuration
[error] Expected ':'
[error] Expected key
[error] Not a valid key: Web-assets (similar: assets)
[error] last wsvc / Web-assets / less
[error] ^
[oat] $ last wsvc / assets / less
[oat] $
This happens with java 11 as well as java 17. I'm using sbt.version=1.9.8 and scala 2.13.12.
If I remove all the target directories, change back to 1.1.0 and recompile, the problem goes away.
I tried the same with your play-scalajs seed but could not reproduce the problem.
The build where I have the issue also has
addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.2")
I tried adding that to the play-scalajs seed but was again unable to reproduce the problem.
I realize there's probably not much that can be done with this, given the lack of a small project that reproduces the issue. But thought I'd register it just in case...
Quoting from @jroper from sbt/sbt#3578 (comment)
I've just had a look at sbt-web-scalajs, and I see what the underlying problem is here. It's looking at what command has been run on the CLI to establish whether to run the fast or full JS command. Doing this is really working against the tool, sbt tasks should be idempotent, invoke it once, invoke it 100 times, doesn't matter the context, it should always return the same result if the files its processing haven't changed. This is a fundamental assumption of sbt, and when you break that assumption, such as the way sbt-web-scalajs does, then things start to break in ways that are really difficult to fix.
Fixing this would probably be quite involved, I'm not that experienced with scala.js to know exactly how it works, but what you'd probably need to do is have it configured to run the fast process initially as a source generator, then produce a directory that all assets are copied to correctly prefixed that can be added to your development classpath (this is something that sbt-web could provide, but I don't think it currently does provide, however, Play framework provides exactly this in its development mode, and that directory is isolated and not included in the final production artifact). Then, you'd add a pipeline stage that does the full build, possibly dropping the dev compiled assets from the pipeline if they are no longer applicable. This would be the idiomatic sbt way of doing things that would work well with other tooling.
Currently, IntelliJ supports debugging of Scala.js project, which emits source map files with absolute path:
Because sbt-web-scalajs ignores relativeSourceMaps
setting, projects based on the plugin cannot be debugged using IntelliJ's Scala plugin.
In Scala 3 the sourceMap compiler option has been changed from -P:scalajs:mapSourceURI:
to -scalajs-mapSourceURI:
, which means that the current version of the plugin is incompatible with Scala 3.
When using Play 2.4 and sbt-play-scalajs v0.2.6, the Scala sources of the client end up being included in the distribution assets JAR. This didn't happen in earlier version of Play.
Scala.js has the ability to concatenate all JS dependencies into a jsdeps file. Currently this plugin does not take this file into account when moving the Scala.js files from the Scala.js projects to the server project.
I for one would like to be able to use this file.
My project structure is mostly based on https://github.com/vmunier/play-scalajs.g8
The current suggestion there is to run packaging with sbt 'set Global / scalaJSStage := FullOptStage' Universal/packageBin
this is ok as a workaround but obviously not ideal compared to being able to set Universal / scalaJSStage := FullOptStage
in build.sbt so that fast opt is the default behaviour and only native packaging configs and tasks use full opt. I'm a little unsure if this setting would go in server or client, i'm guessing client would be preferable in case someone really wants multiple client projects with different opt settings.
I tried looking over the plugin but submitting a PR for it is a little beyond my current knowledge, please consider this enhancement request.
With the configuration skip in packageJSDependencies := false
scalajs compiler creates a file called module-jsdeps.js.
Is nice if the plugin could get automatically this file in @playscalajs.html.scripts("/assets", projectName = "module")
template
Related issue: vmunier/akka-http-scalajs.g8#7
I'm trying to make sure we don't have browsers caching our JS when we deploy a new version of the app. We're using scalajs-bundler.
Is there an option somewhere to specify the final optimised js file name, ie rather than [projectname]-opt-bundle.js or [projectname]-fastopt-bundle.js
I'm struggling to find which plugin is responsible for this so please forgive me if I'm asking in the wrong place.
Thanks
sbt-1.0.0-RC2 was released yesterday http://www.scala-sbt.org/1.0/docs/sbt-1.0-Release-Notes.html#sbt+1.0.0-RC2
After updating from v1.0.11-0.6 to v1.1.0-0.6 we have the following error:
build.sbt:234: error: not found: value devCommands
devCommands in scalaJSPipeline ++= Seq("test", "testOnly", "doc", "~run", "~reStart"),
^
[error] sbt.compiler.EvalException: Type error in expression
There is no more devCommands ?
Is possible to do works it, "sbt-play-scalajs" with spray?, if so, someone could tell me, how can I do that?, I get only Tutorial.scala in the browser, but is empty, :)
The fix for #27 is a step in the right direction I suppose, but it still misses one case.
If I do ~myproject/reStart
everything is fine because it will split on '/'
and get "reStart"
. However if I do project myproject; ~reStart
it doesn't do the right thing because it returns "~reStart"
which doesn't match.
When trying to use the latest plugin in combination with "org.scala-js" % "sbt-scalajs" % "1.0.0-M1", the following error occurs:
[info] Loading global plugins from /home/dstibbe/.sbt/0.13/plugins
[info] Loading project definition from /home/dstibbe/projects/dare-seed/project
java.lang.NoSuchMethodError: org.scalajs.sbtplugin.ScalaJSPlugin$.autoImport()Lorg/scalajs/sbtplugin/ScalaJSPlugin$AutoImport$;
at webscalajs.ScalaJSWeb$.projectSettings(ScalaJSWeb.scala:21)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$autoPluginSettings$1$1$$anonfun$apply$34.apply(Load.scala:721)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$autoPluginSettings$1$1$$anonfun$apply$34.apply(Load.scala:721)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:251)
at scala.collection.AbstractTraversable.flatMap(Traversable.scala:105)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$autoPluginSettings$1$1.apply(Load.scala:721)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$autoPluginSettings$1$1.apply(Load.scala:721)
at sbt.Load$.timed(Load.scala:1025)
at sbt.Load$$anonfun$resolveProject$1.autoPluginSettings$1(Load.scala:720)
at sbt.Load$$anonfun$resolveProject$1.sbt$Load$$anonfun$$expandSettings$1(Load.scala:739)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$sbt$Load$$anonfun$$expandSettings$1$2.apply(Load.scala:740)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$sbt$Load$$anonfun$$expandSettings$1$2.apply(Load.scala:740)
at scala.collection.IndexedSeqOptimized$class.foldl(IndexedSeqOptimized.scala:51)
at scala.collection.IndexedSeqOptimized$class.foldLeft(IndexedSeqOptimized.scala:60)
at scala.collection.mutable.WrappedArray.foldLeft(WrappedArray.scala:34)
at scala.collection.TraversableOnce$class.$div$colon(TraversableOnce.scala:138)
at scala.collection.AbstractTraversable.$div$colon(Traversable.scala:105)
at sbt.Load$$anonfun$resolveProject$1.sbt$Load$$anonfun$$expandSettings$1(Load.scala:740)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$56.apply(Load.scala:743)
at sbt.Load$$anonfun$resolveProject$1$$anonfun$56.apply(Load.scala:743)
at sbt.Load$.timed(Load.scala:1025)
at sbt.Load$$anonfun$resolveProject$1.apply(Load.scala:742)
at sbt.Load$$anonfun$resolveProject$1.apply(Load.scala:703)
at sbt.Load$.timed(Load.scala:1025)
at sbt.Load$.resolveProject(Load.scala:703)
at sbt.Load$.sbt$Load$$finalizeProject$1(Load.scala:603)
at sbt.Load$.discoverAndLoad$1(Load.scala:620)
at sbt.Load$.sbt$Load$$loadTransitive(Load.scala:629)
at sbt.Load$.sbt$Load$$loadTransitive(Load.scala:644)
at sbt.Load$$anonfun$loadUnit$1.sbt$Load$$anonfun$$loadProjects$1(Load.scala:482)
at sbt.Load$$anonfun$loadUnit$1$$anonfun$40.apply(Load.scala:485)
at sbt.Load$$anonfun$loadUnit$1$$anonfun$40.apply(Load.scala:485)
at sbt.Load$.timed(Load.scala:1025)
at sbt.Load$$anonfun$loadUnit$1.apply(Load.scala:485)
at sbt.Load$$anonfun$loadUnit$1.apply(Load.scala:459)
at sbt.Load$.timed(Load.scala:1025)
at sbt.Load$.loadUnit(Load.scala:459)
at sbt.Load$$anonfun$25$$anonfun$apply$14.apply(Load.scala:311)
at sbt.Load$$anonfun$25$$anonfun$apply$14.apply(Load.scala:310)
at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:91)
at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:90)
at sbt.BuildLoader.apply(BuildLoader.scala:140)
at sbt.Load$.loadAll(Load.scala:365)
at sbt.Load$.loadURI(Load.scala:320)
at sbt.Load$.load(Load.scala:316)
at sbt.Load$.load(Load.scala:305)
at sbt.Load$$anonfun$4.apply(Load.scala:146)
at sbt.Load$$anonfun$4.apply(Load.scala:146)
at sbt.Load$.timed(Load.scala:1025)
at sbt.Load$.apply(Load.scala:146)
at sbt.Load$.defaultLoad(Load.scala:39)
at sbt.BuiltinCommands$.liftedTree1$1(Main.scala:503)
at sbt.BuiltinCommands$.doLoadProject(Main.scala:503)
at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:495)
at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:495)
at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:59)
at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:59)
at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:61)
at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:61)
at sbt.Command$.process(Command.scala:93)
at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:96)
at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:96)
at sbt.State$$anon$1.runCmd$1(State.scala:183)
at sbt.State$$anon$1.process(State.scala:187)
at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:96)
at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:96)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.MainLoop$.next(MainLoop.scala:96)
at sbt.MainLoop$.run(MainLoop.scala:89)
at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:68)
at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:63)
at sbt.Using.apply(Using.scala:24)
at sbt.MainLoop$.runWithNewLog(MainLoop.scala:63)
at sbt.MainLoop$.runAndClearLast(MainLoop.scala:46)
at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:30)
at sbt.MainLoop$.runLogged(MainLoop.scala:22)
at sbt.StandardMain$.runManaged(Main.scala:61)
at sbt.xMain.run(Main.scala:35)
at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:109)
at xsbt.boot.Launch$.withContextLoader(Launch.scala:128)
at xsbt.boot.Launch$.run(Launch.scala:109)
at xsbt.boot.Launch$$anonfun$apply$1.apply(Launch.scala:35)
at xsbt.boot.Launch$.launch(Launch.scala:117)
at xsbt.boot.Launch$.apply(Launch.scala:18)
at xsbt.boot.Boot$.runImpl(Boot.scala:41)
at xsbt.boot.Boot$.main(Boot.scala:17)
at xsbt.boot.Boot.main(Boot.scala)
[error] java.lang.NoSuchMethodError: org.scalajs.sbtplugin.ScalaJSPlugin$.autoImport()Lorg/scalajs/sbtplugin/ScalaJSPlugin$AutoImport$;
I have a ScalaJS + Play project with an SBT build file, and am using amongst others the plugin sbt-web-scalajs
. There is a total of 4 subprojects in my build.sbt
. Here's the beginning of that file:
import sbt.Keys.libraryDependencies
val myScalaVersion = "2.13.1"
val scalaTestPlusVersion = "5.1.0"
val scalaJsDomVersion = "1.0.0"
val scalaTagsVersion = "0.8.6"
val scalatagsrxVersion = "0.5.0"
val circeVersion = "0.13.0"
val rosHttpVersion = "3.0.0"
val quillVersion = "3.5.2"
val pgDriverVersion = "42.2.5"
val scriptsVersion = "1.1.4"
val apacheCommonsMailV = "1.5"
useJCenter := true
scalaVersion in ThisBuild := myScalaVersion
scalaJSStage in Global := FullOptStage
lazy val backend = (project in file("backend")).settings(commonSettings).settings(
scalaJSProjects := Seq(frontend, sec_frontend),
pipelineStages in Assets := Seq(scalaJSPipeline),
pipelineStages := Seq(gzip),
pipelineStages := Seq(scalaJSProd, gzip),
compile in Compile := ((compile in Compile) dependsOn scalaJSPipeline).value,
scalaJSStage := FullOptStage,
isDevMode in scalaJSPipeline := false,
libraryDependencies ++= Seq(
"com.vmunier" %% "scalajs-scripts" % scriptsVersion,
jdbc,
evolutions,
"org.postgresql" % "postgresql" % pgDriverVersion,
"org.apache.commons" % "commons-email" % apacheCommonsMailV,
"io.getquill" %% "quill-jdbc" % quillVersion,
"io.circe" %% "circe-core" % circeVersion,
"io.circe" %% "circe-generic" % circeVersion,
"io.circe" %% "circe-parser" % circeVersion,
"org.scalatestplus.play" %% "scalatestplus-play" % scalaTestPlusVersion % "test",
guice,
specs2 % Test
)
).enablePlugins(PlayScala)
.dependsOn(sharedJvm)
lazy val frontend = (project in file("frontend")).settings(commonSettings).settings(
scalaJSUseMainModuleInitializer := true,
scalaJSStage := FullOptStage,
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % scalaJsDomVersion,
"com.lihaoyi" %%% "scalatags" % scalaTagsVersion,
"io.circe" %%% "circe-core" % circeVersion,
"io.circe" %%% "circe-generic" % circeVersion,
"io.circe" %%% "circe-parser" % circeVersion,
"com.github.nondeterministic" %%% "roshttp" % rosHttpVersion,
"com.timushev" %%% "scalatags-rx" % scalatagsrxVersion
),
).enablePlugins(ScalaJSPlugin, ScalaJSWeb)
.dependsOn(sharedJs)
[...]
When I build and then run my project, I have the following artifacts, needed to execute the generated JavaScript code, correctly created:
./frontend/target/scala-2.13/frontend-opt.js
./backend/target/web/classes/main/META-INF/resources/webjars/backend/0.15.0-alpha2/frontend-opt.js
./backend/target/web/public/main/frontend-opt.js
However, a problem arises when I try to update the plugin sbt-web-scalajs
to 1.1 or 1.2 as it no longer supports the isDevMode
flag used in my backend
subproject. That is, if I compile and run my project without it, only one of the three files above is generated:
./frontend/target/scala-2.13/frontend-opt.js
And my ScalaJS/JavaScript frontend fails to load, subsequently. I looked through the documentation of the sbt-web-scalajs
project, which says that all is controlled now via scalaJSStage
, but it doesn't seem to get me the required output files in the required project directories.
In other words, isDevMode
seemingly did more than just control whether fastOpt
or fullOpt
is run, and it is unclear to me how to get the old functionality back.
devCommands in scalaJSPipeline := Seq("run", "compile", "re-start")
should include "reStart", an alternative way to do the "re-start" command
Hi,
First this plugin is just what was missing to the Scala-JS/Play projects, thanks.
I see that we can include the JS by calling playscalajs.html.scripts.
I assume then that the main gets called automatically?
But I'm wondering if we can pass a parameter to this main? Or if we can call another function? With parameters?
Cheers
Continuing to debug #193, this may be related:
In an otherwise empty directory, create build.sbt
, project/plugins.sbt
and project/build.properties
with the following contents:
# Show directory contents
bwbecker@bwbmac sbtDebug % ls -R .
build.sbt project
./project:
build.properties plugins.sbt
# empty build.sbt
bwbecker@bwbmac sbtDebug % cat build.sbt
bwbecker@bwbmac sbtDebug % cat project/build.properties
sbt.version=1.9.8
bwbecker@bwbmac sbtDebug % cat project/plugins.sbt
addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.1.0")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.9.1")
Run sbt:
bwbecker@bwbmac sbtDebug % sbt
[info] welcome to sbt 1.9.8 (Homebrew Java 11.0.19)
[info] loading settings for project global-plugins from plugins.sbt ...
[info] loading global plugins from /Users/bwbecker/.sbt/1.0/plugins
[info] loading settings for project sbtdebug-build from plugins.sbt ...
[info] loading project definition from /Users/bwbecker/temp/sbtDebug/project
java.lang.NoClassDefFoundError: org/webjars/WebJarExtractor$Cache
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at sbt.internal.inc.ModuleUtilities$.getObject(ModuleUtilities.scala:24)
Changing the version of sbt-web-scalajs
to 1.3.0 resolves the problem.
Alternatively, leave sbt-web-scalajs
at 1.1.0 and revert addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.9.1")
to 2.8.21
and add
ThisBuild / libraryDependencySchemes ++= Seq(
"org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
)
This also works.
Conclusion: sbt-web-scalajs
and sbt-plugin
need to be upgraded together. Ideally, this would be checked with a warning. At least document the incompatibility.
Hi,
How to trigger a recompile and copy of resources when the jsclient project is updated?
The follow use case:
Now I do the follow
Today changes in scalajs do not appear in the result of server automatically.
The server recompile is not needed, as it is a resource.
Using version 0.2.4 and play 2.4.0-RC1
Hi @vmunier,
Maybe this is not directly related to your plugin… I need to define a code generator that consumes the web assets produced by sbt-web. I have the following code in my build.sbt
:
(sourceGenerators in Compile) += Def.task {
val assetsDirectory = (WebKeys.public in Assets).value
// Do something with assets
}.taskValue,
Then, when I compile my project, the first time assetsDirectory
contains only “static” assets (those that I defined in src/main/assets
), and no Scala.js generated .js file. If I compile the project a second time, then I get the Scala.js files.
In other words, I need my code generator to run after the sbt-play-scalajs plugin has finished producing its assets.
Any idea of what is wrong with my approach?
Actually, I do not see any play-specific things here, maybe it can be renamed to just sbt-web-scalajs, as it seems to be usable in both play and akka-http projects.
Why are those two files separate in the first place?
Firstly, thanks for your contribution to the community!
Anyway, I am new to scalajs and scalatags, and am looking to migrate a Play application to use both scalatags and scalajs instead of Twirl and javascript.
I started down the road of following your example (split project into server, client, shared, etc.), only to realize the example and plugin were geared toward Twirl support.
Any pointers for scalatags instead of Twirl? I am pursuing a full-scala stack with no direct html or javascript. From what I can see based on playing with your example so far, is that I need a way to put the artifacts (scalajs) that will run on the client into a package that the server-side generated pages can include.
My expected execution for an example page would be:
The sbt workflow would have to put "client" artifacts into a place where they can be served much like other js (e.g. jquery)
Thanks!
Edit: Solved (see comment below)
Since I wanted to use Scala 3 I tried to upgrade to Play Framework 3.0.0, but after upgrading the sbt cli fails already on startup (without providing any command or task) with an error (see below). The error occurs with Scala 2.13.12 or 3.3.1, sbt 1.9.6 or 1.9.7 and play 2.9.0 or 3.0.0. Using the newer play versions or sbt-web-scalajs with Scala 3 individually works however. The only immediate change I found between play 2.9.0 and play 2.8.x is, that Scala 2.12 support has been dropped.
Thanks for the help!
To Reproduce:
sbt new vmunier/play-scalajs.g8
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.0")
oraddSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.9.0")
P.S.: I raised the issue in this repository, because I think it is the most likely one able to address it.
java.lang.NoClassDefFoundError: org/webjars/WebJarExtractor$Cache
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:534)
at java.base/java.lang.Class.forName(Class.java:513)
at sbt.internal.inc.ModuleUtilities$.getObject(ModuleUtilities.scala:24)
at sbt.internal.inc.ModuleUtilities$.getCheckedObject(ModuleUtilities.scala:32)
at sbt.internal.inc.ModuleUtilities$.$anonfun$getCheckedObjects$1(ModuleUtilities.scala:37)
at scala.collection.immutable.Stream.$anonfun$map$1(Stream.scala:418)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1173)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1163)
at scala.collection.generic.Growable.loop$1(Growable.scala:57)
at scala.collection.generic.Growable.$plus$plus$eq(Growable.scala:61)
at scala.collection.generic.Growable.$plus$plus$eq$(Growable.scala:53)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:184)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:47)
at scala.collection.TraversableLike.to(TraversableLike.scala:786)
at scala.collection.TraversableLike.to$(TraversableLike.scala:783)
at scala.collection.AbstractTraversable.to(Traversable.scala:108)
at scala.collection.TraversableOnce.toList(TraversableOnce.scala:350)
at scala.collection.TraversableOnce.toList$(TraversableOnce.scala:350)
at scala.collection.AbstractTraversable.toList(Traversable.scala:108)
at scala.collection.immutable.List.$plus$plus(List.scala:216)
at sbt.internal.PluginDiscovery$.discoverAll(PluginDiscovery.scala:59)
at sbt.internal.Load$.loadPlugins(Load.scala:1330)
at sbt.internal.Load$.loadPluginDefinition(Load.scala:1275)
at sbt.internal.Load$.buildPlugins(Load.scala:1254)
at sbt.internal.Load$.plugins(Load.scala:1233)
at sbt.internal.Load$.$anonfun$loadUnit$2(Load.scala:701)
at sbt.internal.Load$.timed(Load.scala:1407)
at sbt.internal.Load$.$anonfun$loadUnit$1(Load.scala:701)
at sbt.internal.Load$.timed(Load.scala:1407)
at sbt.internal.Load$.loadUnit(Load.scala:695)
at sbt.internal.Load$.$anonfun$builtinLoader$4(Load.scala:493)
at sbt.internal.BuildLoader$.$anonfun$componentLoader$5(BuildLoader.scala:181)
at sbt.internal.BuildLoader.apply(BuildLoader.scala:246)
at sbt.internal.Load$.loadURI$1(Load.scala:555)
at sbt.internal.Load$.loadAll(Load.scala:571)
at sbt.internal.Load$.loadURI(Load.scala:501)
at sbt.internal.Load$.load(Load.scala:480)
at sbt.internal.Load$.$anonfun$apply$1(Load.scala:242)
at sbt.internal.Load$.timed(Load.scala:1407)
at sbt.internal.Load$.apply(Load.scala:242)
at sbt.internal.Load$.defaultLoad(Load.scala:57)
at sbt.BuiltinCommands$.liftedTree1$1(Main.scala:964)
at sbt.BuiltinCommands$.doLoadProject(Main.scala:964)
at sbt.BuiltinCommands$.$anonfun$loadProjectImpl$2(Main.scala:917)
at sbt.Command$.$anonfun$applyEffect$4(Command.scala:151)
at sbt.Command$.$anonfun$applyEffect$2(Command.scala:146)
at sbt.Command$.process(Command.scala:190)
at sbt.MainLoop$.$anonfun$processCommand$5(MainLoop.scala:246)
at scala.Option.getOrElse(Option.scala:189)
at sbt.MainLoop$.process$1(MainLoop.scala:246)
at sbt.MainLoop$.processCommand(MainLoop.scala:279)
at sbt.MainLoop$.$anonfun$next$5(MainLoop.scala:164)
at sbt.State$StateOpsImpl$.runCmd$1(State.scala:290)
at sbt.State$StateOpsImpl$.process$extension(State.scala:326)
at sbt.MainLoop$.$anonfun$next$4(MainLoop.scala:164)
at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:24)
at sbt.MainLoop$.next(MainLoop.scala:164)
at sbt.MainLoop$.run(MainLoop.scala:145)
at sbt.MainLoop$.$anonfun$runWithNewLog$1(MainLoop.scala:120)
at sbt.io.Using.apply(Using.scala:28)
at sbt.MainLoop$.runWithNewLog(MainLoop.scala:113)
at sbt.MainLoop$.runAndClearLast(MainLoop.scala:67)
at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:52)
at sbt.MainLoop$.runLogged(MainLoop.scala:43)
at sbt.StandardMain$.runManaged(Main.scala:225)
at sbt.xMain$.$anonfun$run$11(Main.scala:135)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:62)
at scala.Console$.withIn(Console.scala:230)
at sbt.internal.util.Terminal$.withIn(Terminal.scala:610)
at sbt.internal.util.Terminal$.$anonfun$withStreams$1(Terminal.scala:390)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:62)
at scala.Console$.withOut(Console.scala:167)
at sbt.internal.util.Terminal$.$anonfun$withOut$2(Terminal.scala:600)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:62)
at scala.Console$.withErr(Console.scala:196)
at sbt.internal.util.Terminal$.withOut(Terminal.scala:600)
at sbt.internal.util.Terminal$.withStreams(Terminal.scala:390)
at sbt.xMain$.withStreams$1(Main.scala:88)
at sbt.xMain$.run(Main.scala:123)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at sbt.internal.XMainConfiguration.run(XMainConfiguration.java:59)
at sbt.xMain.run(Main.scala:47)
at xsbt.boot.Launch$.$anonfun$run$1(Launch.scala:149)
at xsbt.boot.Launch$.withContextLoader(Launch.scala:176)
at xsbt.boot.Launch$.run(Launch.scala:149)
at xsbt.boot.Launch$.$anonfun$apply$1(Launch.scala:44)
at xsbt.boot.Launch$.launch(Launch.scala:159)
at xsbt.boot.Launch$.apply(Launch.scala:44)
at xsbt.boot.Launch$.apply(Launch.scala:21)
at xsbt.boot.Boot$.runImpl(Boot.scala:78)
at xsbt.boot.Boot$.run(Boot.scala:73)
at xsbt.boot.Boot$.main(Boot.scala:21)
at xsbt.boot.Boot.main(Boot.scala)
Caused by: java.lang.ClassNotFoundException: org.webjars.WebJarExtractor$Cache
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:593)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.