@emily-curry/snowpack-plugin-wasm-pack
Version:
Snowpack plugin for rust using wasm-pack 🦀
136 lines (135 loc) • 5.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const execa = require("execa");
const fs_1 = require("fs");
const npm_run_path_1 = require("npm-run-path");
const path_1 = require("path");
const snowpack_1 = require("snowpack");
const toml_1 = require("toml");
const getPackageName = (absoluteProjectPath) => {
try {
const cargoToml = toml_1.parse(fs_1.readFileSync(path_1.join(absoluteProjectPath, 'Cargo.toml')).toString('utf-8'));
return cargoToml.package.name;
}
catch (error) {
throw `\
Unable to find RustWasm project at ${absoluteProjectPath}
Please ensure there is a valid Cargo.toml in this directory
See https://rustwasm.github.io/wasm-pack/book/commands/new.html for creating a new project`;
}
};
const snowpackPluginWASMPack = (snowpackConfig, { projectPath, outDir = 'pkg', outName = 'index', logLevel = 'warn', target = 'web', extraArgs = [], scope, wasmPackPath = 'wasm-pack', watch = ['development'], }) => {
const shouldWatch = Array.isArray(watch)
? watch.some((i) => i === snowpackConfig.mode)
: !!watch;
const absoluteProjectPath = path_1.resolve(snowpackConfig.root || process.cwd(), projectPath);
const absolutePackagePath = path_1.join(absoluteProjectPath, outDir);
const packageName = getPackageName(absoluteProjectPath);
const scopedPackageName = `${scope ? `@${scope}/` : ''}${packageName}`;
const pluginName = `wasm-pack-snowpack-plugin [${scopedPackageName}]`;
//
const wasmPackArgs = [
'--log-level',
logLevel,
'build',
'--target',
target,
'--out-dir',
outDir,
'--out-name',
outName,
...(scope ? ['--scope', scope] : []),
...(shouldWatch ? ['--dev'] : []),
...extraArgs,
];
const wasmPackCommandOptions = {
env: npm_run_path_1.env(),
extendEnv: true,
windowsHide: false,
cwd: path_1.join(snowpackConfig.root || process.cwd(), projectPath),
};
// Syncronously execute the build process in non-watch modes, so that the JS is available before the main build pipeline kicks off.
let exitCode;
if (!shouldWatch) {
try {
snowpack_1.logger.info(`[Running '${wasmPackPath} ${wasmPackArgs.join(' ')}']`, {
name: pluginName,
});
const wasmPackResult = execa.sync(wasmPackPath, wasmPackArgs, wasmPackCommandOptions);
const { stdout, stderr } = wasmPackResult;
if (stderr) {
snowpack_1.logger.error(stderr, { name: pluginName });
}
if (stdout) {
snowpack_1.logger.info(stdout, { name: pluginName });
}
exitCode = wasmPackResult.exitCode;
}
catch (e) {
exitCode = e.exitCode;
}
const exitMsg = `[Finished running. Exit status: ${exitCode}]`;
if (exitCode === 0) {
snowpack_1.logger.info(exitMsg, { name: pluginName });
}
else {
snowpack_1.logger.error(exitMsg, { name: pluginName });
}
}
//
const config = (config) => {
var _a, _b;
config.exclude.push(path_1.join('**', projectPath, '/target/**/*'));
config.alias[scopedPackageName] =
(_a = config.alias[scopedPackageName]) !== null && _a !== void 0 ? _a : absolutePackagePath;
config.mount[absolutePackagePath] = (_b = config.mount[absolutePackagePath]) !== null && _b !== void 0 ? _b : {
url: `/dist/${scopedPackageName}`,
static: true,
resolve: true,
};
};
//
const run = async ({ log }) => {
if (!shouldWatch) {
if (exitCode !== 0)
throw new Error('wasm-pack failed to compile project');
else
return;
}
const p = wasmPackPath.replace(/\ /g, '\\ ');
const a = wasmPackArgs.join(' ').replace(/\ /g, '\\ ');
const cmd = `cargo watch -i .gitignore -i pkg/* -s ${p}\\ ${a}`;
const wasmPackProcess = execa.command(cmd, wasmPackCommandOptions);
const stdHandler = (e) => {
let msg = e.toString()
.replace(/\r\n\r\n/g, '\r\n')
.replace(/\n\n/g, '\n');
if (!(msg === null || msg === void 0 ? void 0 : msg.trim()))
return;
if (msg.startsWith('[Running')) {
log('WORKER_RESET', {});
}
log('WORKER_MSG', { msg, level: 'info' });
if (msg.startsWith('[Finished')) {
const match = msg.match(/:\s(\d+)\]/);
const parsed = parseInt(match[1]);
if (parsed !== NaN && parsed > 0) {
log('WORKER_MSG', {
msg: 'wasm-pack failed to compile project',
level: 'error',
});
}
}
};
const { stderr, stdout } = wasmPackProcess;
stderr.on('data', stdHandler);
stdout.on('data', stdHandler);
return await wasmPackProcess;
};
return {
name: pluginName,
run,
config,
};
};
module.exports = snowpackPluginWASMPack;