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

Fix WebpackStats json Reads and update some npm packages #408

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package scalajsbundler

import play.api.libs.json.{JsPath, Json, Reads}
import play.api.libs.json.{Json, Reads}
import sbt._

import scala.util.Try
Expand All @@ -16,8 +16,7 @@ case class NpmPackage(version: String) {
}

object NpmPackage {
implicit val npmPackageDeserializer: Reads[NpmPackage] =
(JsPath \ "version").read[String].map(NpmPackage.apply)
implicit val npmPackageDeserializer: Reads[NpmPackage] = Json.reads[NpmPackage]

def getForModule(targetDir: File, module: String): Option[NpmPackage] = {
val webpackPackageJsonFilePath = targetDir / "node_modules" / module / "package.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,31 @@ object PackageJson {
webpackDevServerVersion: String,
webpackCliVersion: String
): Unit = {
NpmPackage(webpackVersion).major match {
case Some(5) => // ok
case Some(x) => sys.error(s"Unsupported webpack major version $x")
case None => sys.error("No webpack version defined")
}

val npmManifestDependencies = NpmDependencies.collectFromClasspath(fullClasspath)
val dependencies =
npmDependencies ++ (
if (currentConfiguration == Compile) npmManifestDependencies.compileDependencies
else npmManifestDependencies.testDependencies
)

val sourceMapLoaderVersion =
NpmPackage(webpackVersion).major match {
case Some(5) => "2.0.0"
case Some(x) => sys.error(s"Unsupported webpack major version $x")
case None => sys.error("No webpack version defined")
}
// @return package `pkgName` defined in `npmDevDependencies`
// or `name -> defaultVersion` if not defined
val devDependency = (pkgName: String, defaultVersion: String) =>
npmDevDependencies.collectFirst {
case (`pkgName`, v) =>
if (NpmPackage(v).major == NpmPackage(defaultVersion).major) {
pkgName -> v
} else {
sys.error(s"Unsupported $pkgName major version $v")
}
}.getOrElse(pkgName -> defaultVersion)


val devDependencies =
npmDevDependencies ++ (
Expand All @@ -55,9 +67,9 @@ object PackageJson {
"webpack" -> webpackVersion,
"webpack-cli" -> webpackCliVersion,
"webpack-dev-server" -> webpackDevServerVersion,
"concat-with-sourcemaps" -> "1.0.7", // Used by the reload workflow
"source-map-loader" -> sourceMapLoaderVersion // Used by webpack when emitSourceMaps is enabled
)
"concat-with-sourcemaps" -> "1.1.0", // Used by the reload workflow
"source-map-loader" -> "3.0.0" // Used by webpack when emitSourceMaps is enabled
).map(devDependency.tupled)

val packageJson =
JSON.obj(
Expand Down
53 changes: 17 additions & 36 deletions sbt-scalajs-bundler/src/main/scala/scalajsbundler/Stats.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
package scalajsbundler

import play.api.libs.json._
import play.api.libs.functional.syntax._
import sbt.Logger
import scala.math.max
import java.io.File
Expand Down Expand Up @@ -50,18 +49,18 @@ object Stats {

}

final case class WebpackError(moduleName: String, message: String, loc: String)
final case class WebpackError(moduleName: Option[String], message: String, loc: String)

final case class WebpackWarning(moduleName: String, message: String)
final case class WebpackWarning(moduleName: Option[String], message: String)

final case class WebpackStats(
version: String,
hash: String,
time: Long,
time: Option[Long],
outputPath: Option[Path],
errors: List[WebpackError],
warnings: List[WebpackWarning],
assets: List[Asset]
errors: List[WebpackError] = Nil,
warnings: List[WebpackWarning] = Nil,
assets: List[Asset] = Nil
) {

/**
Expand All @@ -70,7 +69,12 @@ object Stats {
def print(log: Logger): Unit = {
import formatting._
// Print base info
List(s"Version: $version", s"Hash: $hash", s"Time: ${time}ms", s"Path: ${outputPath.getOrElse("<default>")}").foreach(x => log.info(x))
List(
s"Version: $version",
s"Hash: $hash",
s"Time: ${time.getOrElse(-1)}ms",
s"Path: ${outputPath.getOrElse("<default>")}"
).foreach(x => log.info(x))
log.info("")
// Print the assets
assets.map { a =>
Expand Down Expand Up @@ -107,32 +111,9 @@ object Stats {
assets.map(a => outputPath.getOrElse(altDir).resolve(a.name).toFile)
}

implicit val assetsReads: Reads[Asset] = (
(JsPath \ "name").read[String] and
(JsPath \ "size").read[Long] and
(JsPath \ "emitted").read[Boolean] and
(JsPath \ "chunkNames").read[List[String]]
)(Asset.apply _)

implicit val errorReads: Reads[WebpackError] = (
(JsPath \ "moduleName").read[String] and
(JsPath \ "message").read[String] and
(JsPath \ "loc").read[String]
)(WebpackError.apply _)

implicit val warningReads: Reads[WebpackWarning] = (
(JsPath \ "moduleName").read[String] and
(JsPath \ "message").read[String]
)(WebpackWarning.apply _)

implicit val statsReads: Reads[WebpackStats] = (
(JsPath \ "version").read[String] and
(JsPath \ "hash").read[String] and
(JsPath \ "time").read[Long] and
(JsPath \ "outputPath").readNullable[String].map(x => x.map(new File(_).toPath)) and // It seems webpack 2 doesn't produce outputPath
(JsPath \ "errors").read[List[WebpackError]] and
(JsPath \ "warnings").read[List[WebpackWarning]] and
(JsPath \ "assets").read[List[Asset]]
)(WebpackStats.apply _)

implicit val assetsReads: Reads[Asset] = Json.reads[Asset]
implicit val errorReads: Reads[WebpackError] = Json.reads[WebpackError]
implicit val warningReads: Reads[WebpackWarning] = Json.reads[WebpackWarning]
implicit val pathReads: Reads[Path] = Reads.StringReads.map(new File(_).toPath)
implicit val statsReads: Reads[WebpackStats] = Json.using[Json.WithDefaultValues].reads[WebpackStats]
}
13 changes: 8 additions & 5 deletions sbt-scalajs-bundler/src/main/scala/scalajsbundler/Webpack.scala
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,13 @@ object Webpack {
case JsSuccess(p, _) =>
if (p.warnings.nonEmpty || p.errors.nonEmpty) {
logger.info("")
// Filtering is a workaround for #111
p.warnings.filterNot(_.message.contains("https://raw.githubusercontent.com")).foreach { warning =>
logger.warn(s"WARNING in ${warning.moduleName}")
p.warnings.foreach { warning =>
logger.warn(s"WARNING in ${warning.moduleName.getOrElse("<default>")}")
logger.warn(warning.message)
logger.warn("\n")
}
p.errors.foreach { error =>
logger.error(s"ERROR in ${error.moduleName} ${error.loc}")
logger.error(s"ERROR in ${error.moduleName.getOrElse("<default>")} ${error.loc}")
logger.error(error.message)
logger.error("\n")
}
Expand Down Expand Up @@ -281,7 +280,11 @@ object Webpack {
*/
def run(nodeArgs: String*)(args: String*)(workingDir: File, log: Logger): Option[WebpackStats] = {
val webpackBin = workingDir / "node_modules" / "webpack" / "bin" / "webpack"
val params = nodeArgs ++ Seq(webpackBin.absolutePath, "--profile", "--json") ++ args
val params = nodeArgs ++ Seq(
webpackBin.absolutePath, "--profile", "--json",
// Filtering is a workaround for #111
"--ignore-warnings-message", """/https:\/\/raw\.githubusercontent\.com/"""
) ++ args
val cmd = "node" +: params
Commands.run(cmd, workingDir, log, jsonOutput(cmd, log)).fold(sys.error, _.flatten)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,9 @@ object ScalaJSBundlerPlugin extends AutoPlugin {

scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.CommonJSModule) },

version in webpack := "5.24.3",
version in webpack := "5.50.0",

webpackCliVersion := "4.5.0",
webpackCliVersion := "4.7.2",

version in startWebpackDevServer := "3.11.2",

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ object Commands {
()
}

logger.debug(s"Command: ${cmd.mkString(" ")}")
logger.info(s"Command: ${cmd.mkString(" ")}")
val process = Process(cmd, cwd)
val processIO = BasicIO.standard(false).withOutput(outputCapture).withError(toErrorLog)
val code: Int = process.run(processIO).exitValue()
Expand Down