Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
25 changes: 7 additions & 18 deletions build.mill
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
//| mill-jvm-version: 21
//| mill-version: 1.0.3
//| mill-version: 1.0.4
//| mvnDeps:
//| - com.lihaoyi::mill-contrib-buildinfo:$MILL_VERSION
//| - com.goyeau::mill-scalafix::0.6.0


package build
//| - io.github.quafadas:millSite_mill1_3.7:0.0.50

import os.copy.over
// import io.github.quafadas.millSite._
import mill._, scalalib._, publish._, scalanativelib._
import mill.scalalib.scalafmt.ScalafmtModule
import mill.util.*
import mill.util.BuildInfo.millVersion

import com.goyeau.mill.scalafix.ScalafixModule
import java.text.Format
// import io.github.quafadas.millSite.SiteModule
import io.github.quafadas.millSite.SiteModule
import mill.util.VcsVersion


object V{
Expand All @@ -27,6 +27,8 @@ object V{
val laminar = "17.2.1"
val scalaJsDom = "2.8.1"
val scalaJs = "1.19.0"
val fs2 = "3.11.0"
val millLibs = mvn"com.lihaoyi::mill-libs:$millVersion"
}

trait FormatFix extends ScalafmtModule with ScalafixModule with ScalaModule
Expand Down Expand Up @@ -67,19 +69,6 @@ trait Testy extends TestModule.Munit with FormatFix {
}


// object site extends SiteModule {

// def scalaVersion = V.scalaVersion
// def unidocDeps = Seq(build.sjsls, build.routes)
// override def unidocTitle = "Scala JS Live Server API"

// override def repoLink = "https://github.com/Quafadas/live-server-scala-cli-js"

// override def latestVersion = "0.2.11"


// }

// SN deps which aren't yet there.
/**
1 targets failed
Expand Down
45 changes: 45 additions & 0 deletions plugin/package.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package build.plugin

import mill.util.BuildInfo. millBinPlatform
import mill._, scalalib._, publish._
import mill.util.VcsVersion
import build.V
import build.FormatFixPublish

object `package` extends ScalaModule with FormatFixPublish:
def platformSuffix = s"_mill$millBinPlatform"

def scalaVersion = build.V.scalaVersion

def scalaArtefactVersion: Task[String] =
scalaVersion.map(_.split("\\.").take(2).mkString("."))

override def artifactName = "sjsls_plugin"

def mvnDeps = Task{
super.mvnDeps() ++
Seq(
V.millLibs,
mvn"co.fs2:fs2-io_3:${V.fs2}"
)
}

def moduleDeps = Seq(build.sjsls)

def artifactSuffix = s"${platformSuffix()}_${scalaArtefactVersion()}"

def publishVersion = VcsVersion.vcsState().format()
// def publishVersion = "DONTUSEME"

override def pomSettings = Task {
PomSettings(
description = "Mill plugin for mdoc, static site generation",
organization = "io.github.quafadas",
url = "https://github.com/Quafadas/millSite",
licenses = Seq(License.`Apache-2.0`),
versionControl = VersionControl.github("quafadas", "millSite"),
developers = Seq(
Developer("quafadas", "Simon Parten", "https://github.com/quafadas")
)
)
}
98 changes: 98 additions & 0 deletions plugin/src/refresh_plugin.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package io.github.quafadas

import io.github.quafadas.sjsls.LiveServerConfig
import mill.*
import mill.scalalib.*
import mill.scalajslib.*

import mill.api.Task.Simple
import fs2.concurrent.Topic
import cats.effect.IO
import cats.effect.unsafe.implicits.global
import io.github.quafadas.sjsls.LiveServerConfig
import mill.api.BuildCtx
import mill.scalajslib.api.Report
implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global

trait ScalaJsRefreshModule extends ScalaJSModule:

lazy val updateServer = Topic[IO, Unit].unsafeRunSync()


def indexHtml = Task{
os.write.over(Task.dest / "index.html", io.github.quafadas.sjsls.vanillaTemplate(withStyles()))
PathRef(Task.dest / "index.html")
}

def assetsDir =
super.moduleDir / "assets"

def withStyles = Task{ true}

def assets = Task.Source{
assetsDir
}

def port = Task {
8080
}

def openBrowser= Task {
true
}

def logLevel = Task {
"warn"
}

def dezombify = Task {
true
}

def siteGen = Task{
val assets_ = assets()
val path = fastLinkJS().dest.path
os.copy.over(indexHtml().path, Task.dest / "index.html")
os.copy(assets_.path, Task.dest, mergeFolders = true)
updateServer.publish1(println("publish update")).unsafeRunSync()
(Task.dest.toString(), assets_.path.toString(), path.toString())

}

def lcs = Task.Worker{
val (site, assets, js) = siteGen()
println("Gen lsc")
LiveServerConfig(
baseDir = None,
outDir = Some(js),
port = com.comcast.ip4s.Port.fromInt(port()).getOrElse(throw new IllegalArgumentException(s"invalid port: ${port()}")),
indexHtmlTemplate = Some(site),
buildTool = io.github.quafadas.sjsls.NoBuildTool(), // Here we are a slave to the build tool
openBrowserAt = "/index.html",
preventBrowserOpen = !openBrowser(),
dezombify = dezombify(),
logLevel = logLevel(),
customRefresh = Some(updateServer)
)
}

def serve = Task.Worker{

println(lcs())
BuildCtx.withFilesystemCheckerDisabled {
new RefreshServer(lcs())
}
}

class RefreshServer(lcs: LiveServerConfig) extends AutoCloseable {
val server = io.github.quafadas.sjsls.LiveServer.main(lcs).allocated

server.map(_._1).unsafeRunSync()

override def close(): Unit = {
// This is the shutdown hook for http4s
println("Shutting down server...")
server.map(_._2).flatten.unsafeRunSync()
}
}

20 changes: 9 additions & 11 deletions site/docs/Configuration/config.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Config

The server is a CLI. It has a number of flags that can be used to configure it. Here is the current list of flags and what they do. You can see these flags by running ` --help` in your terminal.
The CLI launches an http server. It has a number of flags that can be used to configure it. Here is the current list of flags and what they do. You can see these flags by running ` --help` in your terminal.

```
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --help
```sh
cs launch io.github.quafadas::sjsls:latest.version -- --help

```

Expand Down Expand Up @@ -56,7 +56,7 @@ Fire up a terminal in projectDir
```

```sh
cs launch io.github.quafadas::sjsls:{{projectVersion}}
cs launch io.github.quafadas::sjsls:latest.version
```
This is the classic [viteless](https://github.com/Quafadas/viteless/tree/main) example

Expand All @@ -73,7 +73,7 @@ With styles.
Run

```sh
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --styles-dir --fully/qualified/dir/to/styles
cs launch io.github.quafadas::sjsls:latest.version -- --styles-dir --fully/qualified/dir/to/styles
```

## Did I mention I want a full blown SPA?
Expand All @@ -89,7 +89,7 @@ With client side routing under `/app`?
Run

```sh
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --client-routes-prefix app
cs launch io.github.quafadas::sjsls:latest.version -- --client-routes-prefix app
```

## Stop generating my HTML. I want to bring my own.
Expand All @@ -105,7 +105,7 @@ Okay.
```
With
```sh
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- --path-to-index-html fully/qualified/path/to/assets
cs launch io.github.quafadas::sjsls:latest.version -- --path-to-index-html fully/qualified/path/to/assets
```

Note: if you're brining your own html, drop the `--styles` flag - reference `index.less` from your html and read [docs](https://lesscss.org) to get it working in browser.
Expand Down Expand Up @@ -134,7 +134,7 @@ With a backend running on `8080` and a frontend on `3000`, it is configured that
Also, we're now using mill. We need to tell the cli the frontend module name and the directory the compiles JS ends up in.

```sh
cs launch io.github.quafadas::sjsls:{{projectVersion}} -- \
cs launch io.github.quafadas::sjsls:latest.version -- \
--path-to-index-html /Users/simon/Code/mill-full-stack/frontend/ui \
--build-tool mill \
--mill-module-name frontend \
Expand All @@ -153,7 +153,6 @@ This would serve the static site build with the `docJar` tool.
C:\temp\live-server-scala-cli-js> cs launch io.github.quafadas::sjsls:0.2.0 -- --path-to-index-html C:\\temp\\live-server-scala-cli-js\\out\\site\\live.dest\\site --build-tool none --browse-on-open-at /docs/index.html
```

***
You need to include this javascript script tag in the body html - otherwise no page refresh.

```html
Expand All @@ -167,5 +166,4 @@ You need to include this javascript script tag in the body html - otherwise no p
if ("PageRefresh" in msg) location.reload();
});
</script>
```
***
```
3 changes: 3 additions & 0 deletions site/docs/Configuration/library.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Library

The LiveServerConfig can also accept an `fs2.Topic` as a parameter. This allows any tool which can instantiate an `fs2.Topic` to emit a pulse, which will refresh the client. Have a look at the mill plugin code for details.
2 changes: 1 addition & 1 deletion site/docs/advantages.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Here are the key advantages of this approach:

- Because there's no seperate ecosystem or NPM to configure, configuring build and CI is a lot easier. No `node_modules` to worry about. I found that this simplicity infected everything around it.

- In terms of performance; NPM dependancies are loaded out the CDN. This is slow the first time - but seriously - check the network browser tools when you refresh the page. The second time they are all served out of browser cache - it takes 0ms. Even better, that cache _survives application redeployment!_. If you pre-load the (fat) "internal-" xxx dependancies scalaJS produces, this combination crushes page load times.
- In terms of performance; NPM dependancies are loaded out the CDN. This is slow the first time, but check the network browser tools when you refresh the page. The second time they are all served out of browser cache - it takes 0ms. Even better, that cache _survives application redeployment!_.

- You can use the same build tool for both backend and frontend, and share code between them.

Expand Down
4 changes: 2 additions & 2 deletions site/docs/caveats.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ It is usually possible to work around such limitations, but it is not pain free.

I strongly suspect though that as time marches formward ESModules will become the norm, and this limitation will become irrelevant.

# Scale
## Support

This project is not backed by anyone making money from it. Support is therefore ad hoc and limited.
This project is not backed by any power larger than my curiosity.
2 changes: 1 addition & 1 deletion site/docs/deployment.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title: Deployment
Deployment
---

This project targets the dev loop. When comes to deploy however, I always hit the same problem. From discord;
Expand Down
9 changes: 3 additions & 6 deletions site/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@

Paste this into your terminal and hit enter.

${version.latest}

```sh
scala-cli --version && \
cs version && \
git clone https://github.com/Quafadas/viteless.git && \
cd viteless && \
cs launch io.github.quafadas::sjsls:${{version.latest}}
cs launch io.github.quafadas::sjsls:latest.release
```

Note that to work, you need the following directives in scala-cli:
Note that to work, you need cs and scala-cli to be on your path.


## It worked... okay... I have 20 more seconds
Expand All @@ -26,11 +24,10 @@ Edit `hello.scala` and save the change. You should see the change refreshed in y

## Aw shoot - errors

The command above assumes you have coursier (as cs) and scala-cli installed and available on your path.
The command above assumes you have coursier (as cs) and scala-cli and git installed and available on your path.

If you don't have those, consider visiting their respective websites and setting up those tools - they are both excellent and fundamental to the scala ecosystem, you'll need them at some point ...

- [coursier](https://get-coursier.io/docs/cli-installation)
- [scala-cli](https://scala-cli.virtuslab.org)

Once installed, give it another go.
2 changes: 1 addition & 1 deletion site/docs/motivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

I'm a big scala JS fan. However, the reliance on vite for the dev loop / deployment complexified my build piplines to the point where full stack wasn't fun for me anymore. I found maintaining _both_ a JVM setup and a node setup was annoying locally.

And then I had do it again in CI. So, intead of giving up on scala JS and going to write typescript, I figured it would be way more fun to simply try and go 100% scala.
And then I had do it again in CI. So, intead of giving up on scala JS and going to write typescript, I figured it would be way more fun to simply try and go 100% scala - zero friction save, link, refresh.

I wanted to break the dependance on node / npm completely whilst retaining a sane developer experience for browser based scala-js development.
19 changes: 19 additions & 0 deletions site/package.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package build.site

import mill._, scalalib._
import mill.scalajslib.api._
import io.github.quafadas.millSite._
import mill.util.VcsVersion
import build.V

object `package` extends SiteModule {

def moduleDeps = Seq(build.sjsls, build.routes)

override def unidocTitle = "Scala JS Live Server API"

override def repoLink = "https://github.com/Quafadas/live-server-scala-cli-js"

override def latestVersion = VcsVersion.vcsState().lastTag.getOrElse("0.0.0").replace("v", "")

}
Loading
Loading