Skip to content

Commit

Permalink
refactor: update dependencies and exports
Browse files Browse the repository at this point in the history
- Update dependencies. - Update exports. - Remove register file. - Drop the default export and now
use named export Benchmark for the main class.

BREAKING CHANGE: - Drop the default export and now use named export Benchmark for the main class.

fix #2
  • Loading branch information
Masquerade-Circus committed Jun 28, 2022
1 parent a981a4c commit c5b693c
Show file tree
Hide file tree
Showing 17 changed files with 3,305 additions and 1,399 deletions.
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ So, BuffaloBench solves this problem by providing a way to create a benchmarks w

### Simple example
```js
const Benchmark = require('buffalo-bench');
const { Benchmark } = require('buffalo-bench');

// Create a benchmark only with name and function
const bench = new Benchmark("name", async () => {});
Expand All @@ -62,6 +62,8 @@ await bench.run();

### Full example:
```js
const { Benchmark } = require('buffalo-bench');

// Create a benchmark with all the options
const bench = new Benchmark('myBenchmark', {
maxTime: 5, // In seconds
Expand Down Expand Up @@ -92,6 +94,8 @@ await bench.run();

### Suite example:
```js
const { Benchmark } = require('buffalo-bench');

let suite = new Benchmark.Suite("String comparison", {
beforeEach(benchmark) {
console.log(`${this.name}: ${benchmark.name}: Start`);
Expand Down Expand Up @@ -201,7 +205,7 @@ The `Suite` instance has the following methods:
* `getSortedBenchmarksBy(sortedBy: CompareBy)`: Get the benchmarks sorted by a given `CompareBy` metric.
* `getFastest(sortedBy: CompareBy)`: Get the fastest benchmark in the suite sorting by the given `CompareBy` metric.
* `getSlowest(sortedBy: CompareBy)`: Get the slowest benchmark in the suite sorting by the given `CompareBy` metric.
* `CompareFastestWithSlowest(compareBy: CompareBy)`: Compare the fastest benchmark with the slowest benchmark sorting by the given `CompareBy` metric.
* `compareFastestWithSlowest(compareBy: CompareBy)`: Compare the fastest benchmark with the slowest benchmark sorting by the given `CompareBy` metric.
* `run`: Async method that runs the suite.
* `toJSON`: Return a JSON representation of the suite.

Expand Down Expand Up @@ -232,17 +236,17 @@ When converting to JSON, the `errorMessage` property will be a string containing

## Using typescript

If you want to write your benchmarks with typescript, you can use the library as it is by requiring in your project the `buffalo-bench/register` file.
If you want to write your benchmarks with typescript, you must install the `ts-node` library and require in your project the `ts-node/register` file.

Example:

```js
require('buffalo-bench/register');
require('./my-benchmark.ts');)
require('ts-node/register');
require('./my-benchmark.ts');
```

```ts
import Benchmark from 'buffalo-bench';
import { Benchmark } from 'buffalo-bench/lib';

const bench = new Benchmark('myBenchmark', () => {});
(async () => {
Expand All @@ -251,15 +255,11 @@ const bench = new Benchmark('myBenchmark', () => {});
})();
```

This register file uses the `eslint` and `pirates` modules to transpile the typescript code to javascript on the fly.

Take into account that this will not check the typescript code for errors. If you want to check your typescript code, you can must use the `tsc` package.

## Development and Build

- Use `yarn dev` to watch and compile the library on every change to it running the benchmarks in the bench folder.
- Use `yarn dev` to watch and compile the library on every change to it running the index.ts benchmark in the tests folder.
- Use `yarn build` to build the library.
- Use `yarn commit` to commit your changes.
- Use `yarn commit` to commit your changes.

## Contributing

Expand Down
174 changes: 128 additions & 46 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,148 @@ const esbuild = require("esbuild");
const terser = require("terser");
const tsc = require("tsc-prog");
const fs = require("fs");
const zlib = require("zlib");

(async () => {
function convertToUMD(text, globalName) {
// HACK: convert to UMD - only supports cjs and global var
const varName = "__EXPORTS__";
let code = text;
code = code.replace(/export\s*\{([^{}]+)\}/, (_, inner) => {
const defaultExport = inner.match(/^(\w+) as default$/);
return defaultExport != null
? `var ${varName}=${defaultExport[1]}`
: `var ${varName}={${inner.replace(/(\w+) as (\w+)/g, "$2:$1")}}`;
});
code = `(()=>{${code};typeof module!=='undefined'?module.exports=${varName}:self.${globalName}=${varName}})()`;
return code;
}

async function build({
globalName,
entryPoint,
outfileName,
clean = false,
minify = true,
external = []
}) {
try {
let globalName = "Benchmark";
let result = esbuild.buildSync({
entryPoints: ["./lib/index.ts"],
let rootdir = entryPoint.split("/").slice(0, -1).join("/");
let outdir = outfileName.split("/").slice(0, -1).join("/");

let tscProgOptions2 = {
basePath: __dirname, // always required, used for relative paths
configFilePath: "tsconfig.json", // config to inherit from (optional)
files: [entryPoint],
pretty: true,
copyOtherToOutDir: false,
clean: clean ? [outdir] : [],
skipLibCheck: true,
compilerOptions: {
rootDir: rootdir,
declaration: true,
outDir: outdir,
emitDeclarationOnly: true
},
bundleDeclaration: {
entryPoint: "index.d.ts" // relative to the OUTPUT directory ('dist' here)
}
};

tsc.build(tscProgOptions2);

let cjs = esbuild.buildSync({
entryPoints: [entryPoint],
bundle: true,
sourcemap: "external",
write: false,
minify: true,
outdir: "out",
minify: false,
outdir: outdir,
target: "esnext",
loader: { ".js": "jsx", ".ts": "tsx", ".mjs": "jsx" },
format: "esm"
format: "cjs",
metafile: true,
external
});

// HACK: convert to UMD - only supports cjs and global var
const varName = "__EXPORTS__";
let code = result.outputFiles[1].text;
code = code.replace(/export\s*\{([^{}]+)\}/, (_, inner) => {
const defaultExport = inner.match(/^(\w+) as default$/);
return defaultExport != null ? `var ${varName}=${defaultExport[1]}` : `var ${varName}={${inner.replace(/(\w+) as (\w+)/g, "$2:$1")}}`;
});
code = `(()=>{${code};typeof module!=='undefined'?module.exports=${varName}:self.${globalName}=${varName}})()`;

let result2 = await terser.minify(code, {
sourceMap: {
content: result.outputFiles[0].text.toString()
},
compress: {
booleans_as_integers: false
},
output: {
wrap_func_args: false
},
ecma: 2020
let esm = esbuild.buildSync({
entryPoints: [entryPoint],
bundle: true,
sourcemap: "external",
write: false,
minify: false,
outdir: outdir,
target: "esnext",
loader: { ".js": "jsx", ".ts": "tsx", ".mjs": "jsx" },
format: "esm",
metafile: true,
external
});

let mapBase64 = Buffer.from(result2.map.toString()).toString("base64");
let map = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`;
fs.writeFileSync("./dist/index.min.js", result2.code);
fs.writeFileSync("./dist/index.min.js.map", map);
let esmContent = esm.outputFiles[1].text;

let tscProgOptions = {
basePath: process.cwd(), // always required, used for relative paths
configFilePath: "tsconfig.json", // config to inherit from (optional)
files: ["./lib/index.ts"],
pretty: true,
copyOtherToOutDir: false,
clean: ["types"],
compilerOptions: {
rootDir: "./",
declaration: true,
declarationDir: "./types",
emitDeclarationOnly: true
// HACK: simulate __dirname and __filename for esm
if (esmContent.indexOf("__dirname") || esmContent.indexOf("__filename")) {
esmContent =
`import { fileURLToPath } from 'url';\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n` +
esmContent;
if (esmContent.indexOf("import path from") === -1) {
esmContent = `import path from 'path';\n` + esmContent;
}
};
}

fs.writeFileSync(`${outfileName}.mjs`, esmContent);
fs.writeFileSync(`${outfileName}.js`, cjs.outputFiles[1].text);

let text = await esbuild.analyzeMetafile(esm.metafile, { verbose: true });
console.log(text);

tsc.build(tscProgOptions);
let result2;
if (minify) {
let code = convertToUMD(esm.outputFiles[1].text, globalName);
result2 = await terser.minify(code, {
sourceMap: {
content: esm.outputFiles[0].text.toString()
},
compress: {
booleans_as_integers: false
},
output: {
wrap_func_args: false
},
ecma: 2020
});

let mapBase64 = Buffer.from(result2.map.toString()).toString("base64");
let map = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`;
fs.writeFileSync(`${outfileName}.min.js`, result2.code);
fs.writeFileSync(`${outfileName}.min.js.map`, map);
}

function formatBytesToKiloBytes(bytes) {
return (bytes / 1024).toFixed(2) + "kb";
}

let header = `/*** ${entryPoint} ***/`;
console.log(header);
console.log("Esm", formatBytesToKiloBytes(esm.outputFiles[1].text.length));
if (minify) {
console.log("Minified:", formatBytesToKiloBytes(result2.code.length));
// Get the size using gzip compression
const gzip = zlib.gzipSync(result2.code);
console.log("Gzip:", formatBytesToKiloBytes(gzip.length));
// Get the size using brotli algorithm
const brotli = zlib.brotliCompressSync(result2.code);
console.log("Brotli:", formatBytesToKiloBytes(brotli.length));
}
console.log(`/${Array(header.length).fill("*").join("")}/`);
} catch (e) {
console.error(e);
}
})();
}

build({
globalName: "Benchmark",
entryPoint: "./lib/index.ts",
outfileName: "./dist/index",
clean: true
});
Loading

0 comments on commit c5b693c

Please sign in to comment.