browsertime
Version:
Get performance metrics from your web page using Browsertime.
109 lines (101 loc) • 3.09 kB
JavaScript
import path from 'node:path';
import { promisify } from 'node:util';
import {
writeFile as _writeFile,
unlink as _unlink,
readFile as _readFile
} from 'node:fs';
import { pathToFileURL } from 'node:url';
import dayjs from 'dayjs';
import intel from 'intel';
import { toArray } from '../support/util.js';
const log = intel.getLogger('browsertime');
const writeFile = promisify(_writeFile);
const readFile = promisify(_readFile);
const unlink = promisify(_unlink);
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
async function loadFile(script, options, throwError) {
// if the script is an AsyncFunction, return it.
if (script instanceof AsyncFunction) {
return script;
} else if (!script.endsWith('js')) {
// This is an inline script
return script;
}
// If we follow correct naming for modules (.mjs) or commonjs (.cjs)
// we just loads it. .js files is loaded as commonjs if you set
// --cjs true
if (
options.cjs === false ||
script.endsWith('.mjs') ||
script.endsWith('.cjs')
) {
let myFunction = await import(pathToFileURL(path.resolve(script)));
return myFunction.default ?? myFunction;
} else {
// Hack a way! Try to add a package.json file in the same folder as the
// script file. That way, the .js file will be treated as commonjs =
// working as before we moved Browsertime to module
log.info(
'Will try to load load JS as a commonjs file by adding an emtpy package.json'
);
let createdPackageJson = false;
try {
const packageJson = path.join(
path.dirname(path.resolve(script)),
'package.json'
);
try {
await writeFile(packageJson, '{}');
createdPackageJson = true;
} catch {
log.error(
'Could not create package.json file, the %s file will be treated as a esmodule',
script
);
}
const myFunction = await import(path.resolve(script));
try {
if (createdPackageJson) {
await unlink(packageJson);
}
} catch (error) {
log.error(error);
}
return myFunction.default ?? myFunction;
} catch (error) {
// assume the script is a valid inline script by default
if (throwError) {
log.error(
'Could not parse user script %s with error %s',
script,
error
);
throw error;
}
}
}
}
export async function loadPrePostScripts(scripts, options) {
const readScripts = [];
for (let script of toArray(scripts)) {
const loadedScript = await loadFile(script, options, true);
readScripts.push(loadedScript);
}
return readScripts;
}
export async function loadPageCompleteScript(script) {
if (script && script.endsWith('js')) {
return readFile(path.resolve(script), 'utf8');
}
return script;
}
export async function loadScript(script, options, throwError) {
if (script) {
return loadFile(script, options, throwError);
}
return script;
}
export function timestamp() {
return dayjs().format();
}