Skip to content

Commit

Permalink
Feature: SSR Precompiling (JS)
Browse files Browse the repository at this point in the history
This experimental changeset plans to implement precompilation
through Prepack, and potentially compression, for assets embedded
for SSR loading in app JARs.

Changes enclosed:
- Add `prepack` dependency to `graalvm-react`
- Run `prepack` against built code, switch outputs to embed it
- Change default symbol to `.pack.js` variant
  • Loading branch information
sgammon committed Jun 28, 2022
1 parent 43b1aba commit ffcc73c
Show file tree
Hide file tree
Showing 48 changed files with 142 additions and 15 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ allprojects {
kotlinOptions {
apiVersion = Versions.kotlinLanguage
languageVersion = Versions.kotlinLanguage
target = Versions.ecmaVersion
}
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ object Versions {
const val jsUuid = "8.3.2"
const val jsUuidTypes = "8.3.4"
const val kotlinUuid = "0.4.1"
const val ecmaVersion = "v5"
const val prepack = "0.2.54"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import java.io.Serializable
import java.nio.charset.StandardCharsets


val GenerateEsBuildConfig.outputBundleFile
public val GenerateEsBuildConfig.outputBundleFile
get() = File(outputBundleFolder, outputBundleName)

public val GenerateEsBuildConfig.outputPrepackedFile
get() = File(outputBundleFolder, outputPrepackedName)

open class GenerateEsBuildConfig : DefaultTask() {
enum class Mode {
PRODUCTION, DEVELOPMENT
Expand Down Expand Up @@ -41,6 +44,9 @@ open class GenerateEsBuildConfig : DefaultTask() {
@get:Input
var outputBundleName by project.objects.property<String>()

@get:Input
var outputPrepackedName by project.objects.property<String>()

@get:InputFiles
var modulesFolder = project.objects.listProperty(File::class)

Expand All @@ -66,6 +72,7 @@ open class GenerateEsBuildConfig : DefaultTask() {
with(project) {
outputBundleFolder = file("$buildDir\\bundle").absolutePath
outputBundleName = "bundle.js"
outputPrepackedName = "bundle.pack.js"
modulesFolder.set(listOf(
file("node_modules"),
file("${project.rootDir}/build/js/node_modules"),
Expand All @@ -79,8 +86,9 @@ open class GenerateEsBuildConfig : DefaultTask() {

@get:Input
val configTemplate = """
const fs = require('fs');
const esbuild = require('esbuild');
const alias = require('esbuild-plugin-alias');
const Prepack = require('prepack');
const nodePath = process.env.NODE_PATH;
if (!nodePath) {
throw new Error("Failed to resolve NODE_PATH");
Expand All @@ -100,10 +108,24 @@ open class GenerateEsBuildConfig : DefaultTask() {
'%%%PROCESS%%%'
]
};
esbuild.build(
settings
).catch(() => process.exit(1));
const prepacked = Prepack.prepackFileSync([
'%%%OUTFILE%%%'
], {
compatibility: 'browser',
inlineExpressions: true,
timeout: 300 * 60 * 1000,
sourceMaps: false,
filename: 'ssr.js'
});
fs.writeFileSync('%%%PACKEDFILE%%%', prepacked.code, {
encoding: 'utf8'
});
""".trimIndent()

@get:Input
Expand All @@ -126,6 +148,7 @@ open class GenerateEsBuildConfig : DefaultTask() {
.replace("%%%MINIFY%%%", minify.toString())
.replace("%%%LIBNAME%%%", libraryName)
.replace("%%%PLATFORM%%%", platform)
.replace("%%%PACKEDFILE%%%", outputPrepackedFile.absolutePath.fixSlashes())
.replace("%%%PROCESS%%%", processShim.absolutePath.fixSlashes())
.replace("%%%OUTFILE%%%", outputBundleFile.absolutePath.fixSlashes())
.replace("%%%NODEPATH%%%", modulesFolder.get().joinToString(",") {
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Settins: Build
buildSamples=true
buildPlugins=true
elide.buildMode=dev
elide.stamp=false
elide.lockDeps=false
Expand Down
2 changes: 1 addition & 1 deletion images/codespace/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ RUN echo "Setting up Debian-based codespace..." \
&& chown "$DEV_USER" "/home/$DEV_USER/.zshrc" "/home/$DEV_USER/.alias" \
&& mkdir -p /home/dev/bin \
&& curl -o /home/dev/bin/ibazel "https://github.com/bazelbuild/bazel-watcher/releases/download/$IBAZEL_VERSION/ibazel_linux_amd64" \
&& gcloud components install -y kubectl \
&& yes Y | gcloud components install kubectl \
&& echo "Codespace image ready."

USER ${DEV_USER}
Expand Down
2 changes: 1 addition & 1 deletion packages/graalvm-react/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ publishing {

dependencies {
api(npm("esbuild", Versions.esbuild))
api(npm("esbuild-plugin-alias", Versions.esbuildPluginAlias))
api(npm("prepack", Versions.prepack))
api(npm("buffer", Versions.nodeBuffers))
api(npm("readable-stream", Versions.nodeStreams))
implementation(project(":packages:graalvm-js"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import java.nio.charset.StandardCharsets
private const val embeddedRoot = "embedded"

// Production script name default.
private const val nodeProdDefault = "node-prod.js"
private const val nodeProdDefault = "node-prod.pack.js"

// Development script name default.
private const val nodeDevDefault = "node-dev.js"
private const val nodeDevDefault = "node-dev.pack.js"

// Default name if no mode is specified or resolvable.
const val nodeSsrDefaultPath = nodeDevDefault
Expand Down
16 changes: 16 additions & 0 deletions packages/server/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@file:Suppress("UnstableApiUsage", "unused", "UNUSED_VARIABLE")

import java.net.URI
import com.google.protobuf.gradle.*

plugins {
java
Expand All @@ -13,6 +14,7 @@ plugins {
kotlin("plugin.atomicfu")
kotlin("plugin.serialization")
id("com.adarshr.test-logger")
id("com.google.protobuf")
id("io.micronaut.library")
id("org.jetbrains.dokka")
id("org.sonarqube")
Expand All @@ -21,6 +23,12 @@ plugins {
group = "dev.elide"
version = rootProject.version as String

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${Versions.protobuf}"
}
}

kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(Versions.javaLanguage))
Expand Down Expand Up @@ -123,6 +131,14 @@ micronaut {
version.set(Versions.micronaut)
}

sourceSets {
named("main") {
proto {
srcDir("${rootProject.projectDir}/proto")
}
}
}

dependencies {
// API Deps
api("jakarta.inject:jakarta.inject-api:2.0.1")
Expand Down
12 changes: 10 additions & 2 deletions samples/fullstack/react-ssr/node/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
import elide.dev.buildtools.gradle.tasks.GenerateEsBuildConfig
import elide.dev.buildtools.gradle.tasks.GenerateEsBuildConfig.Mode
import elide.dev.buildtools.gradle.tasks.GenerateEsBuildConfig.Mode.*
import elide.dev.buildtools.gradle.tasks.outputBundleFile
import elide.dev.buildtools.gradle.tasks.outputPrepackedFile
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask
import java.util.*

Expand Down Expand Up @@ -92,6 +92,14 @@ tasks {
}
append(".js")
}
outputPrepackedName = buildString {
append(project.name)
when (mode) {
PRODUCTION -> append("-prod")
DEVELOPMENT -> append("-dev")
}
append(".pack.js")
}
outputBundleFolder = file("$buildDir/distributions").absolutePath
processShim = file("$buildDir/esbuild/process-shim.js")
outputConfig = file("$buildDir/esbuild/esbuild.${modeName.toLowerCase()}.js")
Expand All @@ -114,7 +122,7 @@ tasks {
inputs.file(generateEsBuildConfig.processShim)
inputs.file(generateEsBuildConfig.outputConfig)
inputs.file(fixNodeFetch.destinationDir / "ssr.js")
outputs.file(generateEsBuildConfig.outputBundleFile)
outputs.file(generateEsBuildConfig.outputPrepackedFile)
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions samples/fullstack/ssr/node/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ tasks {
}
append(".js")
}
outputPrepackedName = buildString {
append(project.name)
when (mode) {
PRODUCTION -> append("-prod")
DEVELOPMENT -> append("-dev")
}
append(".pack.js")
}
outputBundleFolder = file("$buildDir/distributions").absolutePath
processShim = file("$buildDir/esbuild/process-shim.js")
outputConfig = file("$buildDir/esbuild/esbuild.${modeName.toLowerCase()}.js")
Expand Down
7 changes: 7 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include(
)

val buildSamples: String by settings
val buildPlugins: String by settings

if (buildSamples == "true") {
include(
Expand All @@ -36,6 +37,12 @@ if (buildSamples == "true") {
)
}

if (buildPlugins == "true") {
includeBuild(
"tools/plugin/gradle-plugin",
)
}

gradleEnterprise {
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
31 changes: 31 additions & 0 deletions tools/plugin/gradle-plugin/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[versions]
detekt = "1.20.0"
kotlin = "1.7.0"
ktlintGradle = "10.3.0"
pluginPublish = "0.21.0"
pluginProtobuf = "0.8.18"
versionCheck = "0.42.0"
sonar = "3.4.0.2513"
protobuf = "3.20.1"
kotlinx_serialization = "1.3.3"
truth = "1.1.3"

[plugins]
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt"}
kotlin = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin"}
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlintGradle"}
sonar = { id = "org.sonarqube", version.ref = "sonar" }
protobuf = { id = "com.google.protobuf", version.ref = "pluginProtobuf" }
pluginPublish = { id = "com.gradle.plugin-publish", version.ref = "pluginPublish"}
versionCheck = { id = "com.github.ben-manes.versions", version.ref = "versionCheck"}

[libraries]
junit = "junit:junit:4.13.2"
protobuf_java = { group = "com.google.protobuf", name = "protobuf-java", version.ref = "protobuf" }
protobuf_util = { group = "com.google.protobuf", name = "protobuf-java-util", version.ref = "protobuf" }
protobuf_kotlin = { group = "com.google.protobuf", name = "protobuf-kotlin", version.ref = "protobuf" }
kotlinx_serialization_core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core", version.ref = "kotlinx_serialization" }
kotlinx_serialization_json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx_serialization" }
kotlinx_serialization_protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf", version.ref = "kotlinx_serialization" }
truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
truth_proto = { group = "com.google.truth.extensions", name = "truth-proto-extension", version.ref = "truth" }
File renamed without changes.
32 changes: 32 additions & 0 deletions tools/plugin/gradle-plugin/plugin-build/model/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import com.google.protobuf.gradle.*

plugins {
kotlin("jvm")
alias(libs.plugins.protobuf)
}

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${libs.plugins.protobuf.get()}"
}
}

dependencies {
api(kotlin("gradle-plugin"))
implementation(kotlin("stdlib-jdk7"))
implementation(libs.protobuf.java)
implementation(libs.protobuf.kotlin)
implementation(libs.protobuf.util)
implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.serialization.protobuf)

testImplementation(libs.junit)
testImplementation(libs.truth)
testImplementation(libs.truth.proto)
}

java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ dependencyResolutionManagement {

rootProject.name = ("dev.elide.buildtools.gradle")

include(":plugin")
include(
":model",
":plugin"
)
File renamed without changes.
Binary file not shown.

This file was deleted.

0 comments on commit ffcc73c

Please sign in to comment.