Skip to content

Instantly share code, notes, and snippets.

@lifeart
Created November 21, 2022 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lifeart/c9c3e8a339dc57210cfdb8da5fbf99ac to your computer and use it in GitHub Desktop.
Save lifeart/c9c3e8a339dc57210cfdb8da5fbf99ac to your computer and use it in GitHub Desktop.
Instrument vite build using nyc
// @ts-check
const fs = require('fs');
const path = require('path');
const os = require('os');
var { spawn } = require('child_process');
const systemCpuCores = os.cpus();
const pathToArtifacts = path.join(__dirname, '..', 'build', 'assets');
const processes = systemCpuCores.length > 1 ? systemCpuCores.length - 1 : 1;
const files = fs.readdirSync(pathToArtifacts);
const filesToInstrument = files
.map((el) => {
const meta = path.parse(el);
const shouldProcess =
meta.ext === '.js' &&
!meta.name.startsWith('vendor') &&
!meta.name.includes('.min.');
const fullPath = path.join(pathToArtifacts, el);
return shouldProcess
? {
name: el,
fullPath,
size: fs.statSync(fullPath).size,
}
: null;
})
.filter((e) => e !== null)
.sort((a, b) => {
return b.size - a.size;
});
const poolQueue = new Array(processes).fill(null).map((_) => []);
let poolIndex = 0;
filesToInstrument.forEach((file) => {
poolQueue[poolIndex].push(file.fullPath);
poolIndex++;
if (poolIndex === processes) {
poolIndex = 0;
}
});
async function processInThread(items) {
for (let file of items) {
await new Promise((resolve, reject) => {
const child = spawn('node', [path.join(__dirname, 'worker__instrument-file.js'), file], {
env: {
...process.env,
NODE_OPTIONS: '--max-old-space-size=8096',
},
});
child.stderr.on('data', (data) => {
console.error(Buffer.from(data).toString());
});
child.on('close', (code) => {
if (code !== 0) {
reject(code);
} else {
resolve('');
}
});
});
}
}
async function processFiles(chunks) {
const promises = chunks.map((files) => {
return processInThread(files);
});
await Promise.all(promises);
}
console.time('instrument');
processFiles(poolQueue)
.catch((e) => {
console.error(e);
})
.then(() => {
console.timeEnd('instrument');
});
// @ts-check
const filePath = process.argv[2];
const babel = require('@babel/core');
const babelPluginIstanbul = require('babel-plugin-istanbul');
const fs = require('fs');
async function transformFile(fullFileName) {
var result = await babel.transformFileAsync(fullFileName, {
babelrc: false,
compact: false,
sourceMaps: true,
configFile: false,
inputSourceMap: JSON.parse(fs.readFileSync(fullFileName + '.map', 'utf8')),
plugins: [
[
babelPluginIstanbul,
{
include: ['**/*.js'],
},
],
],
});
fs.writeFileSync(fullFileName, result?.code ?? '', 'utf8');
fs.writeFileSync(fullFileName + '.map', JSON.stringify(result?.map), 'utf8');
}
transformFile(filePath);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment