forked from scala-js/vite-plugin-scalajs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
86 lines (71 loc) · 2.79 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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<string> {
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);
let fullOutput: string = '';
child.stdout!.setEncoding('utf-8');
child.stdout!.on('data', data => {
fullOutput += data;
process.stdout.write(data); // tee on my own stdout
});
return new Promise((resolve, reject) => {
child.on('error', err => {
reject(new Error(`sbt invocation for Scala.js compilation could not start. Is it installed?\n${err}`));
});
child.on('close', code => {
if (code !== 0) {
let errorMessage = `sbt invocation for Scala.js compilation failed with exit code ${code}.`;
if (fullOutput.includes("Not a valid command: --")) {
errorMessage += "\nCause: Your sbt launcher script version is too old (<1.3.3)."
errorMessage += "\nFix: Re-install the latest version of sbt launcher script from https://www.scala-sbt.org/"
}
reject(new Error(errorMessage));
} else {
resolve(fullOutput.trimEnd().split('\n').at(-1)!);
}
});
});
}
export interface ScalaJSPluginOptions {
cwd?: string,
projectID?: string,
uriPrefix?: string,
}
export default function scalaJSPlugin(options: ScalaJSPluginOptions = {}): VitePlugin {
const { cwd, projectID, uriPrefix } = options;
const fullURIPrefix = uriPrefix ? (uriPrefix + ':') : 'scalajs:';
let isDev: boolean | undefined = undefined;
let scalaJSOutputDir: string | undefined = undefined;
return {
name: "scalajs:sbt-scalajs-plugin",
// Vite-specific
configResolved(resolvedConfig) {
isDev = resolvedConfig.mode === 'development';
},
// standard Rollup
async buildStart(options) {
if (isDev === undefined)
throw new Error("configResolved must be called before buildStart");
const task = isDev ? "fastLinkJSOutput" : "fullLinkJSOutput";
const projectTask = projectID ? `${projectID}/${task}` : task;
scalaJSOutputDir = await printSbtTask(projectTask, cwd);
},
// standard Rollup
resolveId(source, importer, options) {
if (scalaJSOutputDir === undefined)
throw new Error("buildStart must be called before resolveId");
if (!source.startsWith(fullURIPrefix))
return null;
const path = source.substring(fullURIPrefix.length);
return `${scalaJSOutputDir}/${path}`;
},
};
}