diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b379e69b..9ef73fd9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -41,7 +41,7 @@ jobs: apps: sbt - name: scala-js build - run: sbt ";language-server-apiJS/fullOptJS;aqua-apiJS/fullLinkJS" + run: sbt ";language-server-apiJS/fullBundleJS;aqua-apiJS/fullBundleJS" - name: Import secrets uses: hashicorp/vault-action@v2.7.3 diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 075b54d4..c1653c37 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -51,7 +51,7 @@ jobs: - name: scala-js build env: SNAPSHOT: ${{ steps.version.outputs.id }} - run: sbt ";language-server-apiJS/fastOptJS;aqua-apiJS/fastLinkJS" + run: sbt ";language-server-apiJS/fastBundleJS;aqua-apiJS/fastBundleJS" - name: Import secrets uses: hashicorp/vault-action@v2.7.3 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8fe8a35e..0da0a560 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -82,7 +82,7 @@ jobs: apps: sbt - name: aqua-api build - run: sbt "aqua-apiJS/fastLinkJS" + run: sbt "aqua-apiJS/fastBundleJS" - name: Setup pnpm uses: pnpm/action-setup@v2.4.0 diff --git a/.gitignore b/.gitignore index e2219a84..b0fb5f2d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,8 @@ project/target .DS_Store -language-server/language-server-npm/aqua-lsp-api.j* -api/api-npm/api-dist-js +language-server/language-server-npm/aqua-lsp-api.js +api/api-npm/aqua-api.js integration-tests/src/compiled/* diff --git a/api/api-npm/index.js b/api/api-npm/index.js index 2bb0d9bf..de48ef13 100644 --- a/api/api-npm/index.js +++ b/api/api-npm/index.js @@ -1,4 +1,4 @@ -import { AquaConfig, Aqua, Call, Input, Path } from "./api-dist-js/main.js"; +import { AquaConfig, Aqua, Call, Input, Path } from "./aqua-api.js"; function getConfig({ constants = [], diff --git a/api/api-npm/package.json b/api/api-npm/package.json index 33b34fc9..1cb12d4d 100644 --- a/api/api-npm/package.json +++ b/api/api-npm/package.json @@ -7,7 +7,7 @@ "files": [ "index.js", "index.d.ts", - "api-dist-js/main.js", + "aqua-api.js", "meta-utils.js" ], "prettier": {}, diff --git a/build.sbt b/build.sbt index d2482776..54371fa3 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,5 @@ +import BundleJS.* + val aquaVersion = "0.12.1" val scalaV = "3.3.1" @@ -74,12 +76,10 @@ lazy val `language-server-api` = crossProject(JSPlatform, JVMPlatform) lazy val `language-server-apiJS` = `language-server-api`.js .settings( - // TODO: move to fast/fullLinkJS here - Compile / fastOptJS / artifactPath := baseDirectory.value / "../../language-server-npm" / "aqua-lsp-api.js", - Compile / fullOptJS / artifactPath := baseDirectory.value / "../../language-server-npm" / "aqua-lsp-api.js", scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule)), scalaJSUseMainModuleInitializer := true ) + .settings(addBundleJS("../../language-server-npm/aqua-lsp-api.js")) .enablePlugins(ScalaJSPlugin) .dependsOn(`js-exports`, `js-imports`) @@ -104,12 +104,11 @@ lazy val `aqua-api` = crossProject(JSPlatform, JVMPlatform) lazy val `aqua-apiJS` = `aqua-api`.js .settings( - Compile / fastLinkJS / scalaJSLinkerOutputDirectory := baseDirectory.value / "../../api-npm/api-dist-js", - Compile / fullLinkJS / scalaJSLinkerOutputDirectory := baseDirectory.value / "../../api-npm/api-dist-js", scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.ESModule)), scalaJSUseMainModuleInitializer := true, Test / test := {} ) + .settings(addBundleJS("../../api-npm/aqua-api.js")) .enablePlugins(ScalaJSPlugin) .dependsOn(`js-exports`) diff --git a/js/js-imports/src/main/scala/aqua/js/Npm.scala b/js/js-imports/src/main/scala/aqua/js/Npm.scala index d8e15bd0..06e711e6 100644 --- a/js/js-imports/src/main/scala/aqua/js/Npm.scala +++ b/js/js-imports/src/main/scala/aqua/js/Npm.scala @@ -9,7 +9,7 @@ object Meta { // it is needed for `createRequire` function // TODO: Investigate if it is really needed @js.native - @JSImport("../meta-utils.js", "metaUrl") + @JSImport("./meta-utils.js", "metaUrl") val metaUrl: String = js.native } diff --git a/project/BundleJS.scala b/project/BundleJS.scala new file mode 100644 index 00000000..c9b6177c --- /dev/null +++ b/project/BundleJS.scala @@ -0,0 +1,56 @@ +import sbt.* +import sbt.Keys.* + +import org.scalajs.linker.interface.Report +import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport.* + +/** + * Utility to add bundling js functionality to a project. + */ +object BundleJS { + // Bundle full js (result of fullLinkJS) + val fullBundleJS = taskKey[Unit]("Full bundle JS") + // Bundle fast js (result of fastLinkJS) + val fastBundleJS = taskKey[Unit]("Fast bundle JS") + + /** + * Add full/fast bundle JS tasks to a project. + * + * @param outputFilePath **relative to baseDirectory** path to output file + * @return Seq of settings with tasks + */ + def addBundleJS( + outputFilePath: String // TODO: Accept `File` + ) = Seq( + fullBundleJS := Def.taskDyn { + bundleJS(fullLinkJS, outputFilePath) + }.value, + fastBundleJS := Def.taskDyn { + bundleJS(fastLinkJS, outputFilePath) + }.value + ) + + private def bundleJS( + linkJSTask: TaskKey[Attributed[Report]], + outputFilePath: String + ) = Def.taskDyn { + val logger = streams.value.log + + val jsDir = (Compile / linkJSTask / scalaJSLinkerOutputDirectory).value + val linkResult = (Compile / linkJSTask).value + val outputFile = baseDirectory.value / outputFilePath + + linkResult.data.publicModules.toList match { + case Nil => + throw new RuntimeException("No public modules generated") + case _ :: _ :: _ => + throw new RuntimeException("More than one public module generated") + case module :: Nil => + val jsFile = jsDir / module.jsFileName + Def.task { + logger.info(s"Copying $jsFile to $outputFile") + IO.copyFile(jsFile, outputFile) + } + } + } +}