I'm developing a Play 2.4 application and would like SBT to run webpack to generate static assets during compilation.
I tried https://github.com/stejskal/sbt-webpack but it does't seem to work for me.
I managed to have it work by defining a custom sbt task that is used a dependence for dist and stage tasks invoked when you package your application.
The code of the task is straight forward :
lazy val webpack = taskKey[Unit]("Run webpack when packaging the application")
def runWebpack(file: File) = {
Process("webpack", file) !
}
webpack := {
if(runWebpack(baseDirectory.value) != 0) throw new Exception("Something goes wrong when running webpack.")
}
dist <<= dist dependsOn webpack
stage <<= stage dependsOn webpack
In dev mode I use play action hooks to run webpack watch when the code changes :
PlayKeys.playRunHooks <+= baseDirectory.map(Webpack.apply)
with Webpackdefined as follows :
import java.net.InetSocketAddress
import play.sbt.PlayRunHook
import sbt._
object Webpack {
def apply(base: File): PlayRunHook = {
object WebpackHook extends PlayRunHook {
var process: Option[Process] = None
override def beforeStarted() = {
process = Option(
Process("webpack", base).run()
)
}
override def afterStarted(addr: InetSocketAddress) = {
process = Option(
Process("webpack --watch", base).run()
)
}
override def afterStopped() = {
process.foreach(_.destroy())
process = None
}
}
WebpackHook
}
}
It works like a charm. You find at my github account a sample play project using this technique : https://github.com/nouhoum/play-react-webpack/blob/master/webpack.sbt
I hope this helps ;-)
Nouhoum's answer was working fine until I updated to SBT 1.0.x
Just a few updates were needed:
import scala.sys.process.Process
lazy val webpack = taskKey[Unit]("Run webpack when packaging the application")
def runWebpack(file: File) = {
Process("npm run build", file) !
}
webpack := {
if(runWebpack(baseDirectory.value) != 0) throw new Exception("Something went wrong when running webpack.")
}
dist := (dist dependsOn webpack).value
stage := (stage dependsOn webpack).value
We've built sbt-webpack that integrates cleanly with the incremental compilation with Playframework's static assets. I hope that what you want. It works as expected with sbt run and sbt stage.
At GIVE.asia, We are using it for packaging Vue, Axios, and Vue-i18 into a single JS file, which is later included in our HTML file. Then, we use expose-loader to expose the variables Vue, VueI18n, and axios.
The reason to prefer sbt-webpack is that it generates the output file to an appropriate location that can be used by Playframework's routing. Because it integrates with the incremental compilation with Playframework's static assets.
Here's the repo: https://github.com/GIVESocialMovement/sbt-webpack
Or you can jump directly to a working example: https://github.com/GIVESocialMovement/sbt-webpack/tree/master/test-play-project
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With