Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -720,14 +720,14 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
isFullOpt <- builds.head.options.scalaJsOptions.fullOpt
linkerConfig = builds.head.options.scalaJsOptions.linkerConfig(logger)
linkResult <- linkJs(
builds,
destPath,
mainClass,
builds = builds,
dest = destPath,
mainClassOpt = mainClass,
addTestInitializer = false,
linkerConfig,
isFullOpt,
builds.head.options.scalaJsOptions.noOpt.getOrElse(false),
logger
config = linkerConfig,
fullOpt = isFullOpt,
noOpt = builds.head.options.scalaJsOptions.noOpt.getOrElse(false),
logger = logger
)
} yield linkResult

Expand Down Expand Up @@ -1023,48 +1023,52 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
builds.head.options.archiveCache
)
}
val relMainJs = os.rel / "main.js"
val relSourceMapJs = os.rel / "main.js.map"
val mainJs = linkingDir / relMainJs
val sourceMapJs = linkingDir / relSourceMapJs

if (os.exists(mainJs))
if (
os.walk.stream(linkingDir)
.filter(_ != mainJs)
.filter(_ != sourceMapJs)
.headOption
.nonEmpty
) {
// copy linking dir to dest
os.copy(
linkingDir,
dest,
createFolders = true,
replaceExisting = true,
mergeFolders = true
)
os.walk.stream(linkingDir).filter(_.ext == "js").toSeq match {
case Seq(sourceJs) if os.isFile(sourceJs) && sourceJs.last.endsWith(".js") =>
// there's just one js file to link, so we copy it directly
logger.debug(
s"Scala.js linker generate multiple files for js multi-modules. Copy files to $dest directory."
s"Scala.js linker generated single file ${sourceJs.last}. Copying it to $dest"
)
dest / "main.js"
}
else {
os.copy(mainJs, dest, replaceExisting = true)
if (builds.head.options.scalaJsOptions.emitSourceMaps && os.exists(sourceMapJs)) {
val sourceMapJs = os.Path(sourceJs.toString + ".map")
os.copy(sourceJs, dest, replaceExisting = true)
if builds.head.options.scalaJsOptions.emitSourceMaps && os.exists(sourceMapJs) then {
logger.debug(
s"Source maps emission enabled, copying source map file: ${sourceMapJs.last}"
)
val sourceMapDest =
builds.head.options.scalaJsOptions.sourceMapsDest.getOrElse(os.Path(s"$dest.map"))
val updatedMainJs = ScalaJsLinker.updateSourceMappingURL(dest)
os.write.over(dest, updatedMainJs)
os.copy(sourceMapJs, sourceMapDest, replaceExisting = true)
logger.message(s"Emitted js source maps to: $sourceMapDest")
}

dest
}
else {
val found = os.walk(linkingDir).map(_.relativeTo(linkingDir))
value(Left(new ScalaJsLinkingError(relMainJs, found)))
case _ @Seq(jsSource, _*) =>
os.copy(
linkingDir,
dest,
createFolders = true,
replaceExisting = true,
mergeFolders = true
)
logger.debug(
s"Scala.js linker generated multiple files for js multi-modules. Copied files to $dest directory."
)
val jsFileToReturn = os.rel / {
mainClassOpt match {
case Some(_) if os.exists(linkingDir / "main.js") => "main.js"
case Some(mc) if os.exists(linkingDir / s"$mc.js") => s"$mc.js"
case _ => jsSource.relativeTo(linkingDir)
}
}
dest / jsFileToReturn
case Nil =>
logger.debug("Scala.js linker did not generate any .js files.")
val allFilesInLinkingDir = os.walk(linkingDir).map(_.relativeTo(linkingDir))
value(Left(new ScalaJsLinkingError(
expected = if mainClassOpt.nonEmpty then "main.js" else "<module>.js",
foundFiles = allFilesInLinkingDir
)))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1485,4 +1485,26 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
}
}
}

if actualScalaVersion.startsWith("3") then
test("package Scala.js without a main method") {
val moduleName = "whatever"
TestInputs(
os.rel / s"$moduleName.scala" ->
s"""import scala.scalajs.js.annotation.*
|
|object $moduleName {
| @JSExportTopLevel(name = "handler", moduleID = "$moduleName")
| def handler(): Unit = {
| println("Hello world!")
| }
|}
|""".stripMargin
).fromRoot { root =>
val res =
os.proc(TestUtil.cli, "package", ".", "--js", "--power", extraOptions)
.call(cwd = root, mergeErrIntoOut = true, stderr = os.Pipe)
expect(res.out.trim().contains(s"$moduleName.js"))
}
}
}