scalacenter / bloop

Bloop is a build server and CLI tool to compile, test and run Scala fast from any editor or build tool.
https://scalacenter.github.io/bloop/
Apache License 2.0
902 stars 202 forks source link

How to get bloop link single scala.js file for Slinky #634

Open jatcwang opened 6 years ago

jatcwang commented 6 years ago

Hello, I'm trying to get bloop running with Slinky's example project (https://slinky.shadaj.me/docs/installation/) to avoid the SBT overhead

I figured to get hot reloading I'll need to run webpack in a separate terminal, but looking at the docs I can't seem to figure out how to run fastOptJS in bloop.

I tried bloop link my-app and got

[E] No main classes were found in the project 'my-app'

which I think is due to slinky using a JS file as the main file (to perform webpack hot reloading):

require("./my-app-fastopt.js").entrypoint.main();

if (module.hot) {
    module.hot.accept();
}

So I guess the question then becomes: Is there a way to run fastOptJS by itself?

jvican commented 6 years ago

👋 @jatcwang This is a use case I care much about, thanks for the ticket.

The issue here is that we don't support scalaJSUseMainModuleInitializer, which automatically adds the Main class in the project as a main class. The reason why it's not added by default is because it doesn't have the right signature, it lacks the parameters args: Array[String] in the main definition. Here's the special support for this feature in the scala.js sbt plugin: https://github.com/scala-js/scala-js/blob/0ff1fbe3f7a003482c3b785b6a374202f44f47c1/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala#L306-L310. (A PR fixing that would be much welcome; you can add support for that in our sbt plugin by invoking the scalaJSMainModuleInitializer in a similar way as we invoke other ScalaJS sbt settings/tasks https://github.com/scalacenter/bloop/blob/master/integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/SbtBloop.scala#L144-L145)

A workaround for the previous behavior can be done if you add the args: Array[String] parameter to the signature of the main method.

However, even with that workaround, Bloop fails with:

➜  my-app bloop link my-app
Compiling 1 Scala source to /private/tmp/my-app/.bloop/my-app/scala-2.12/classes ...
Done compiling.
[E] hello.world.AppCSS$ needs to be imported from module 'resources/App.css' but module support is disabled.
[E] hello.world.IndexCSS$ needs to be imported from module 'resources/index.css' but module support is disabled.
[E] hello.world.ReactLogo$ needs to be imported from module 'resources/logo.svg' but module support is disabled.
[E] Could not generate JavaScript file

I have no idea why that happens, but the linker doesn't seem to be getting the right resources. @tindzk has a better understanding of the Scala.js integration than I do, so maybe he knows how to fix this problem or has already run into it? It looks like it's related to how modules are supported in our linker.

tindzk commented 6 years ago

The problem is that our link method in Interpreter always looks for main classes. This is not desired when the user sets the kind to commonjs because Scala.js exports the code as a module and not as a top-level script. We also do not have an entry point for Scala.js test cases which is why I had to change the bridges in my pull request #572 to take an optional main class. Once this has been merged, I can come up with a fix.

jvican commented 5 years ago

@tindzk Your changes https://github.com/scalacenter/bloop/pull/572 eventually made it into master, I had to rework some areas to make sure that we didn't break compatibility of the configuration file format, we had cancellation working correctly and a few more things. If you can help fixing this issue, that would be very much appreciated.

tindzk commented 5 years ago

Great, thanks. I will look into this issue.