This repository has been archived by the owner on Aug 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
86 lines (69 loc) · 3.11 KB
/
index.js
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 {execAsync} from 'async-child-process';
import fse from 'fs-extra';
import loaderUtils from 'loader-utils';
import path from 'path';
import glob from 'glob';
import toml from 'toml';
const defaultConfig = {
flags: '',
bin: false,
release: true,
verbose: false,
features: ""
};
const getCrateRoot = async function(childPath) {
let candidate = childPath;
while (candidate !== path.parse(candidate).root) {
const maybeCargoFile = path.join(candidate, 'Cargo.toml');
if (await fse.pathExists(maybeCargoFile)) {
return candidate;
}
candidate = path.dirname(candidate);
}
return null;
};
const load = async function(self) {
/// Retrieve the crate root
const crateRoot = await getCrateRoot(self.resourcePath);
if (!crateRoot) {
throw new Error('No Cargo.toml file found.');
}
/// Add dependencies on the rust source files
// glob(`src/**/*.rs`, {
// cwd: crateRoot
// }, (err, files) => {
// console.log(err, files);
// files.forEach( (file) => self.addDependency(file) );
// });
// self.dependency('src/wasm/websocket-api/Cargo.toml');
/// Load the options and the Cargo.toml
const opts = Object.assign(defaultConfig, loaderUtils.getOptions(self));
const crateConfig = toml.parse(await fse.readFile(path.join(crateRoot, 'Cargo.toml'), 'utf8'));
/// Check if a binary name is set otherwise use the package name as the expected binary output name
let binaryName = opts.bin ? opts.bin : crateConfig.package.name;
if (opts.verbose) console.log("Current binary file name:", binaryName);
/// Refactor the options to fit the cargo-web syntax
opts.bin = opts.bin ? `--bin ${opts.bin}` : '';
opts.release = opts.release ? '--release' : '';
/// Execute cargo-web
const cmd = `cargo web build --target-webasm ${opts.bin} ${opts.release} ${opts.flags}`;
if (opts.verbose) console.log("Running cargo-web:", cmd);
const result = await execAsync(cmd, {cwd: crateRoot});
if (opts.verbose) console.log("Cargo log output:", result.stdout, result.stderr);
/// Check if the output files are where they should be
const outputDirectory = path.join(crateRoot, `./target/wasm32-unknown-unknown/${opts.release ? 'release' : 'debug'}`);
let wasmFile = path.join(outputDirectory, `./${binaryName}.wasm`);
let runtimeFile = path.join(outputDirectory, `./${binaryName}.js`);
if ( !(await fse.pathExists(wasmFile) && await fse.pathExists(runtimeFile)) ) {
throw new Error('No wasm file and/or runtime produced as build output', null);
}
/// Read the runtime and make it webpack-compatible
// TODO The replace calls shouldn't be necessary but instead the runtime in the cargo-web repo should be adapted
let runtimeFileContent = await fse.readFile(runtimeFile, 'utf8');
runtimeFileContent = runtimeFileContent.replace(/fetch\((.+?)\)/g, `fetch(require('${wasmFile}'))`);
return runtimeFileContent;
};
module.exports = function() {
const callback = this.async();
load(this).then(r => callback(null, r), e => callback(e, null));
};