@swell/cli
Version:
Swell's command line interface/utility
56 lines (55 loc) • 2.18 kB
JavaScript
import * as esbuild from 'esbuild';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
export async function bundleFunction(filePath) {
try {
const buildResult = await esbuild.build({
bundle: true,
entryPoints: [filePath],
format: 'cjs',
metafile: true,
platform: 'node',
target: ['chrome58'],
write: false, // Do not write the output to a file
});
const { metafile: { inputs }, outputFiles: [{ text: origCode }], } = buildResult;
// TODO: make a separate method to get dependencies for watch command
const dependencies = Object.keys(inputs).filter((input) => !input.startsWith('node_modules/'));
let code = origCode
.split('\n')
.map((line) => line.trim().startsWith('module.exports')
? line.replace('module.exports', 'var moduleExports')
: line)
.join('\n');
// Remove comments with to get a unique hash in the API
// Because esbuild puts the file name as a comment
code = code.replaceAll(/^\n?\/\/.*/gm, '');
// eslint-disable-next-line no-new-func
const evalFn = new Function(`${code}\nreturn { ...moduleExports }`);
const { config, ...moduleExports } = evalFn();
code = await minifyCode(code + getSwellFunctionWrapper());
return { code, config, dependencies, moduleExports };
}
catch (error) {
throw new Error(`Unable to compile function ${filePath}: ${error.message}`);
}
}
function getSwellFunctionWrapper() {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
return fs.readFileSync(path.join(__dirname, './swell-function-wrapper.js'), 'utf8');
}
async function minifyCode(code) {
try {
const result = await esbuild.transform(code, {
minifyIdentifiers: false,
minifySyntax: false,
minifyWhitespace: true,
});
return result.code;
}
catch (error) {
throw new Error('Compilation error:', error.message);
}
}