Skip to content

Commit e61d27a

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

File tree

12 files changed

+2229
-0
lines changed

12 files changed

+2229
-0
lines changed

.github/workflows/ci.yml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Node.js test and Build
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
strategy:
12+
matrix:
13+
os: [ubuntu-latest, windows-latest]
14+
node-version: ['16']
15+
java: ['8']
16+
17+
runs-on: ${{ matrix.os }}
18+
19+
steps:
20+
- uses: actions/checkout@v3
21+
- name: Use Node.js ${{ matrix.node-version }}
22+
uses: actions/setup-node@v3
23+
with:
24+
node-version: ${{ matrix.node-version }}
25+
- name: Set up JDK ${{ matrix.java }}
26+
uses: actions/setup-java@v3
27+
with:
28+
distribution: 'adopt'
29+
java-version: ${{ matrix.java }}
30+
cache: 'sbt'
31+
32+
- name: Cache dependencies
33+
uses: actions/cache@v3
34+
with:
35+
path: |
36+
**/node_modules
37+
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
38+
39+
- name: Install dependencies
40+
run: npm install
41+
- name: Run sbt once in the test project to make sure sbt is downloaded
42+
run: sbt projects
43+
working-directory: ./test/testproject
44+
- name: Perform unit test
45+
run: npm test
46+
- name: Build
47+
run: npm run build

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/node_modules/
2+
/dist/
3+
target/

index.ts

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { spawn, SpawnOptions } 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", "-no-colors", "-Dsbt.supershell=false", `print ${task}`];
7+
const options: SpawnOptions = {
8+
cwd: cwd,
9+
stdio: ['ignore', 'pipe', 'inherit'],
10+
};
11+
const child = process.platform === 'win32'
12+
? spawn("sbt.bat", args.map(x => `"${x}"`), {shell: true, ...options})
13+
: spawn("sbt", args, options);
14+
15+
let fullOutput: string = '';
16+
17+
child.stdout!.setEncoding('utf-8');
18+
child.stdout!.on('data', data => {
19+
fullOutput += data;
20+
process.stdout.write(data); // tee on my own stdout
21+
});
22+
23+
return new Promise((resolve, reject) => {
24+
child.on('error', err => {
25+
reject(new Error(`sbt invocation for Scala.js compilation could not start. Is it installed?\n${err}`));
26+
});
27+
child.on('close', code => {
28+
if (code !== 0)
29+
reject(new Error(`sbt invocation for Scala.js compilation failed with exit code ${code}.`));
30+
else
31+
resolve(fullOutput.trimEnd().split('\n').at(-1)!);
32+
});
33+
});
34+
}
35+
36+
export interface ScalaJSPluginOptions {
37+
cwd?: string,
38+
projectID?: string,
39+
uriPrefix?: string,
40+
}
41+
42+
export default function scalaJSPlugin(options: ScalaJSPluginOptions = {}): VitePlugin {
43+
const { cwd, projectID, uriPrefix } = options;
44+
45+
const fullURIPrefix = uriPrefix ? (uriPrefix + ':') : 'scalajs:';
46+
47+
let isDev: boolean | undefined = undefined;
48+
let scalaJSOutputDir: string | undefined = undefined;
49+
50+
return {
51+
name: "scalajs:sbt-scalajs-plugin",
52+
53+
// Vite-specific
54+
configResolved(resolvedConfig) {
55+
isDev = resolvedConfig.mode === 'development';
56+
},
57+
58+
// standard Rollup
59+
async buildStart(options) {
60+
if (isDev === undefined)
61+
throw new Error("configResolved must be called before buildStart");
62+
63+
const task = isDev ? "fastLinkJSOutput" : "fullLinkJSOutput";
64+
const projectTask = projectID ? `${projectID}/${task}` : task;
65+
scalaJSOutputDir = await printSbtTask(projectTask, cwd);
66+
},
67+
68+
// standard Rollup
69+
resolveId(source, importer, options) {
70+
if (scalaJSOutputDir === undefined)
71+
throw new Error("buildStart must be called before resolveId");
72+
73+
if (!source.startsWith(fullURIPrefix))
74+
return null;
75+
const path = source.substring(fullURIPrefix.length);
76+
77+
return `${scalaJSOutputDir}/${path}`;
78+
},
79+
};
80+
}

0 commit comments

Comments
 (0)