Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scala.js packaging should produce NoModule by default #338

Closed
keynmol opened this issue Nov 2, 2021 · 5 comments · Fixed by #342
Closed

Scala.js packaging should produce NoModule by default #338

keynmol opened this issue Nov 2, 2021 · 5 comments · Fixed by #342
Labels

Comments

@keynmol
Copy link
Contributor

keynmol commented Nov 2, 2021

TL;DR: when packaging scala-cli and scalajs plugin have different defaults:

scala-cli defaults to CommonJS module type:

Whereas Scala.js when used as SBT plugin defaults to NoModule: https://github.com/scala-js/scala-js/blob/9f7012281eda7185f64e9c3824cf316f2b761081/linker-interface/shared/src/main/scala/org/scalajs/linker/interface/StandardConfig.scala#L73

❯ cat chris.scala
// using scala 2.13.6
// using scala-js
import $dep.`org.scala-js::scalajs-dom::2.0.0`

import org.scalajs.dom
import org.scalajs.dom.document
import scala.scalajs.js.annotation.JSExportTopLevel

object Main extends App {
  def appendPar(targetNode: dom.Node, text: String): Unit = {
    val parNode = document.createElement("p")
    parNode.textContent = text
    targetNode.appendChild(parNode)
  }
  @JSExportTopLevel("addClickedMessage")
  def addClickedMessage(): Unit = {
    appendPar(document.body, "You clicked the button!")
  }
}
❯ scala-cli package chris.scala -f && (cat chris.js | grep addClickedMessage)
Compiling project (Scala 2.13.6, Scala.JS)
Compiled project (Scala 2.13.6, Scala.JS)
Wrote chris.js, run it with
  node ./chris.js
$c_LMain$.prototype.addClickedMessage__V = (function() {
exports.addClickedMessage = (function() {
  $m_LMain$().addClickedMessage__V()
❯ scala-cli package chris.scala --js-module-kind none -f && (cat chris.js | grep addClickedMessage)
Wrote chris.js, run it with
  node ./chris.js
let addClickedMessage;
$c_LMain$.prototype.addClickedMessage__V = (function() {
addClickedMessage = (function() {
  $m_LMain$().addClickedMessage__V()

Current default means you can't run the packaged script in the browser without altering configuration.

Stems from a Discord discusion

@romanowski romanowski added good first issue Good for newcomers Scala.js labels Nov 2, 2021
ckipp01 added a commit to ckipp01/scala-cli that referenced this issue Nov 3, 2021
This better aligns with the defaults users coming from sbt land or going
to sbt where Scalajs will default to NoModule. This also allows a JS
file produced by package to more easily be incuded in an html file if no
further linking is required.

Closes VirtusLab#338
@alexarchambault
Copy link
Contributor

I think I went for common-js by default so that the generated files can be run straightaway with node. For the cases illustrated in the Scala CLI tests at least (like running munit tests).

As the failing tests in #342 show, no-module creates issues when depending on munit for example, that seems to require file system-related APIs (which it gets via the fs module on node, so that some module support is required).

So I'm shared about making no-module the default. --js-module-kind none ought to work for the case described above.

@sjrd
Copy link

sjrd commented Nov 15, 2021

Isn't that an MUnit issue (scalameta/munit#114, scalameta/munit#247), which was fixed in scalameta/munit#376, part of v0.7.27?

@ckipp01
Copy link
Contributor

ckipp01 commented Nov 16, 2021

I think I went for common-js by default so that the generated files can be run straightaway with node

I'm actually curious, what is the most common use case, running the created script with node, or trying to include it in a webpage?

So I'm shared about making no-module the default. --js-module-kind none ought to work for the case described above.

Gotcha, for a bit of context I think if someone is trying this out and reading through https://scala-cli.virtuslab.org/docs/guides/scala-js and trying to follow the ScalaJS docs will get tripped up on this. Since they'll probably think that they can just include the generated file in their html file like the ScalaJS docs talk about.

I have no issue passing --js-module-kind none in, but I do think beginners will trip up on this.

@sjrd
Copy link

sjrd commented Nov 16, 2021

I think I went for common-js by default so that the generated files can be run straightaway with node

I'm actually curious, what is the most common use case, running the created script with node, or trying to include it in a webpage?

The scripts generated for NoModule are also supposed to run straightaway with Node.js. This is how they are run and tested by default with sbt-scalajs. ;) It was only an MUnit-specific issue that they didn't, which, as I mentioned above, I think is fixed.

@ckipp01
Copy link
Contributor

ckipp01 commented Nov 16, 2021

The scripts generated for NoModule are also supposed to run straightaway with Node.js. This is how they are run and tested by default with sbt-scalajs. ;) It was only an MUnit-specific issue that they didn't, which, as I mentioned above, I think is fixed.

Ahh ok, that's even better then.

alexarchambault pushed a commit that referenced this issue Dec 9, 2021
This better aligns with the defaults users coming from sbt land or going
to sbt where Scalajs will default to NoModule. This also allows a JS
file produced by package to more easily be incuded in an html file if no
further linking is required.

Closes #338
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants