Skip to content

Commit 440d099

Browse files
committed
Initial implementation.
1 parent 242ce05 commit 440d099

File tree

12 files changed

+2083
-0
lines changed

12 files changed

+2083
-0
lines changed

.github/workflows/ci.yml

Lines changed: 47 additions & 0 deletions
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

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", "-no-colors", "-Dsbt.supershell=false", `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)