clientBuilder service
import { build } from 'esbuild';
import { promisify } from 'util';
import { writeFile, readFile } from 'fs';
import { dirSync } from 'tmp';
import { Client } from '../client.js';
let buildPromise;
export default {
create(){
return this.defer(() => this);
},
async build(options = {}){
const { force = false } = options;
if(!buildPromise || force){
buildPromise = this._build();
}
return buildPromise;
},
async _build(){
const { name: tmpDir, removeCallback: deleteTmpDir } = dirSync({ unsafeCleanup: true });
const inFile = `${tmpDir}/in.js`;
const outFile = `${tmpDir}/out.js`;
await promisify(writeFile)(inFile, Client.instance.modules.map((_, i) => `import ${JSON.stringify(`${tmpDir}/module-${i}.js`)};`).join('\n'));
for(let i = 0; i < Client.instance.modules.length; i++){
await promisify(writeFile)(`${tmpDir}/module-${i}.js`, Client.instance.modules[i]);
}
await build({
entryPoints: [inFile],
bundle: true,
sourcemap: true,
outfile: outFile,
plugins: [this.plugin],
nodePaths: await this.project.nodePaths,
minify: process.env.NODE_ENV == 'production'
});
const out = {
js: (await promisify(readFile)(outFile, 'utf8')).replace(/\/\/#.*?$/m, ''),
map: await promisify(readFile)(`${outFile}.map`, 'utf8'),
};
await deleteTmpDir();
return out;
},
get plugin(){
return {
name: 'blognami',
async setup(build){
build.onLoad({ filter: /\.js$/ }, async args => {
const { path } = args;
const contents = await promisify(readFile)(path, 'utf8');
if(!contents.match(/blognami-if-client/)) return;
const alteredContents = contents.replace(/(.*)\/\/\s*blognami-if-client:\s*(.*)/g, '$2 // blognami-if-server: $1');
return { contents: alteredContents, loader: 'js' };
});
}
};
}
};