Skip to content

Commit b8ca73d

Browse files
committed
Initial implementation.
1 parent 242ce05 commit b8ca73d

File tree

11 files changed

+2020
-0
lines changed

11 files changed

+2020
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/node_modules/
2+
/dist/
3+
target/

index.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { spawn, SpawnOptionsWithoutStdio } from "child_process";
2+
import type { Plugin as VitePlugin } from "vite";
3+
4+
// Utility to invoke a given sbt task and fetch its output
5+
function printSbtTask(task: string, cwd?: string): Promise<string> {
6+
const args = ["--batch", `print ${task}`];
7+
const options: SpawnOptionsWithoutStdio = {
8+
cwd: cwd,
9+
};
10+
const child = process.platform === 'win32'
11+
? spawn("sbt.bat", args.map(x => `"${x}"`), {shell: true, ...options})
12+
: spawn("sbt", args, options);
13+
14+
let fullOutput: string = '';
15+
16+
child.stdout.setEncoding('utf-8');
17+
child.stdout.on('data', data => {
18+
fullOutput += data;
19+
process.stdout.write(data); // tee on my own stdout
20+
});
21+
22+
child.stderr.setEncoding('utf-8');
23+
child.stderr.on('data', data => {
24+
process.stderr.write(data); // tee on my own stderr
25+
});
26+
27+
return new Promise((resolve, reject) => {
28+
child.on('close', code => {
29+
if (code !== 0)
30+
reject(new Error(`sbt invocation for Scala.js compilation failed with exit code ${code}`));
31+
else
32+
resolve(fullOutput.trimEnd().split('\n').at(-1)!);
33+
})
34+
})
35+
}
36+
37+
export interface ScalaJSPluginOptions {
38+
projectID?: string,
39+
cwd?: string,
40+
}
41+
42+
export default function scalaJSPlugin(options: ScalaJSPluginOptions = {}): VitePlugin {
43+
const { projectID, cwd } = options;
44+
45+
let isDev = false; // when resolving the Vite config, this may turn into true
46+
let scalaJSOutputDir: string;
47+
48+
return {
49+
name: "scalajs:sbt-scalajs-plugin",
50+
51+
// Vite-specific
52+
configResolved(resolvedConfig) {
53+
isDev = resolvedConfig.mode === 'development';
54+
},
55+
56+
// standard Rollup
57+
async buildStart(options) {
58+
const task = isDev ? "fastLinkJSOutput" : "fullLinkJSOutput";
59+
const projectTask = projectID ? `${projectID}/${task}` : task;
60+
scalaJSOutputDir = await printSbtTask(projectTask, cwd);
61+
},
62+
63+
// standard Rollup
64+
resolveId(source, importer, options) {
65+
const parts = /^scalajs:(.*)$/g.exec(source);
66+
if (!parts)
67+
return null;
68+
69+
return `${scalaJSOutputDir}/${parts[1]}`;
70+
},
71+
};
72+
}

0 commit comments

Comments
 (0)