From 683346af29a114adedf325f836a1567b04baa907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20P=C5=99=C3=ADhoda?= Date: Thu, 11 May 2023 08:18:21 +0200 Subject: [PATCH 1/2] Configuration option to specify SBT launcher. Allows to use 'sbtn' for much quicker vite start in case the sbt server is running. --- README.md | 4 ++++ index.ts | 18 +++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ec49a11..76dc205 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,10 @@ export default defineConfig({ // URI prefix of imports that this plugin catches (without the trailing ':') // default: 'scalajs' (so the plugin recognizes URIs starting with 'scalajs:') uriPrefix: 'scalajs', + + // SBT launcher executable to use, 'sbt' by default on Linux, 'sbt.bat' on Windows + // Set to 'sbtn' to use the sbt server for quicker vite startup + launcher: 'sbtn', }), ], }); diff --git a/index.ts b/index.ts index 5bfcf5d..0296fc5 100644 --- a/index.ts +++ b/index.ts @@ -2,15 +2,15 @@ import { spawn, SpawnOptions } from "child_process"; import type { Plugin as VitePlugin } from "vite"; // Utility to invoke a given sbt task and fetch its output -function printSbtTask(task: string, cwd?: string): Promise { +function printSbtTask(task: string, cwd?: string, launcher?: string): Promise { const args = ["--batch", "-no-colors", "-Dsbt.supershell=false", `print ${task}`]; const options: SpawnOptions = { cwd: cwd, stdio: ['ignore', 'pipe', 'inherit'], }; const child = process.platform === 'win32' - ? spawn("sbt.bat", args.map(x => `"${x}"`), {shell: true, ...options}) - : spawn("sbt", args, options); + ? spawn(launcher || "sbt.bat", args.map(x => `"${x}"`), { shell: true, ...options }) + : spawn(launcher || "sbt", args, options); let fullOutput: string = ''; @@ -27,8 +27,11 @@ function printSbtTask(task: string, cwd?: string): Promise { child.on('close', code => { if (code !== 0) reject(new Error(`sbt invocation for Scala.js compilation failed with exit code ${code}.`)); - else - resolve(fullOutput.trimEnd().split('\n').at(-1)!); + else { + // SBTN does send ANSI escape codes even with -no-color, and adds extra log message at the end + // Filter out all lines that start with an escape code and logs (starting with [), take last line + resolve(fullOutput.trimEnd().split('\n').filter(line => !/^\x1b?\[/.test(line)).at(-1)!) + } }); }); } @@ -37,10 +40,11 @@ export interface ScalaJSPluginOptions { cwd?: string, projectID?: string, uriPrefix?: string, + launcher?: string, } export default function scalaJSPlugin(options: ScalaJSPluginOptions = {}): VitePlugin { - const { cwd, projectID, uriPrefix } = options; + const { cwd, projectID, uriPrefix, launcher } = options; const fullURIPrefix = uriPrefix ? (uriPrefix + ':') : 'scalajs:'; @@ -62,7 +66,7 @@ export default function scalaJSPlugin(options: ScalaJSPluginOptions = {}): ViteP const task = isDev ? "fastLinkJSOutput" : "fullLinkJSOutput"; const projectTask = projectID ? `${projectID}/${task}` : task; - scalaJSOutputDir = await printSbtTask(projectTask, cwd); + scalaJSOutputDir = await printSbtTask(projectTask, cwd, launcher); }, // standard Rollup From c464aa04e830351dc67465db1962a52bd26c1565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20P=C5=99=C3=ADhoda?= Date: Sat, 3 Jun 2023 21:30:00 +0200 Subject: [PATCH 2/2] Fix the escape codes --- index.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/index.ts b/index.ts index 0296fc5..48b76b6 100644 --- a/index.ts +++ b/index.ts @@ -29,8 +29,16 @@ function printSbtTask(task: string, cwd?: string, launcher?: string): Promise !/^\x1b?\[/.test(line)).at(-1)!) + const p = fullOutput + .trimEnd() + // Remove the clear screen escape code + .replace(/\u001b\[\d+J/g, '') + .split('\n') + // Filter empty lines and the extra log message (starting with [) + .filter(line => !/^($|\x1b?\[)/.test(line)) + // Last line + .at(-1) + resolve(p || ''); } }); });