124 lines
4.8 KiB
TypeScript
124 lines
4.8 KiB
TypeScript
/**
|
|
* Command definitions for the `effect-bundle` bundle-size CLI.
|
|
*
|
|
* This module wires the top-level `bundle` command to the reporting service and
|
|
* exposes the workflows used when maintaining fixture bundle sizes. `compare`
|
|
* builds the package's local fixtures and compares them with matching fixture
|
|
* files from another checkout, `report` bundles an explicit list of entrypoints
|
|
* and prints a Markdown table, `compare-selected` compares explicit entrypoints
|
|
* against a base checkout, `visualize-selected` analyzes explicit entrypoints,
|
|
* and `visualize` prompts for local fixtures before producing visualization
|
|
* output for inspection.
|
|
*
|
|
* Command output is intentionally split by workflow. `compare` requires an
|
|
* existing `--base-dir` (`-b`) and writes its Markdown report to `--output-path`
|
|
* (`-o`), defaulting to `stats.txt` resolved from the current working directory.
|
|
* `report` accepts one or more existing files and writes to stdout. `visualize`
|
|
* uses `--output-dir` (`-o`) for generated bundle artifacts, so `-o` names a
|
|
* file for `compare` but a directory for `visualize`.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
import * as Console from "effect/Console"
|
|
import * as Effect from "effect/Effect"
|
|
import * as FileSystem from "effect/FileSystem"
|
|
import * as Path from "effect/Path"
|
|
import * as Argument from "effect/unstable/cli/Argument"
|
|
import * as Command from "effect/unstable/cli/Command"
|
|
import * as Flag from "effect/unstable/cli/Flag"
|
|
import * as Prompt from "effect/unstable/cli/Prompt"
|
|
import { Fixtures } from "./Fixtures.ts"
|
|
import { Reporter } from "./Reporter.ts"
|
|
|
|
const baseDirectory = Flag.directory("base-dir", { mustExist: true }).pipe(
|
|
Flag.withAlias("b"),
|
|
Flag.withDescription("The base directory to use for bundle size comparisons")
|
|
)
|
|
|
|
const outputPath = Flag.file("output-path").pipe(
|
|
Flag.withAlias("o"),
|
|
Flag.withDescription("The name of the file to write the bundle size report to"),
|
|
Flag.withDefault("stats.txt"),
|
|
Flag.mapEffect(Effect.fnUntraced(function*(outputPath) {
|
|
const path = yield* Path.Path
|
|
return path.resolve(outputPath)
|
|
}))
|
|
)
|
|
|
|
const compare = Command.make("compare", { baseDirectory, outputPath }).pipe(
|
|
Command.withHandler(Effect.fnUntraced(function*({ baseDirectory, outputPath }) {
|
|
const fs = yield* FileSystem.FileSystem
|
|
const reporter = yield* Reporter
|
|
const report = yield* reporter.report({ baseDirectory })
|
|
yield* fs.writeFileString(outputPath, report)
|
|
yield* Effect.log(`Bundle size report written to: '${outputPath}'`)
|
|
}))
|
|
)
|
|
|
|
const outputDirectory = Flag.directory("output-dir").pipe(
|
|
Flag.withAlias("o"),
|
|
Flag.withDescription("The name of the directory to write the bundle size visualizations to"),
|
|
Flag.mapEffect(Effect.fnUntraced(function*(outputPath) {
|
|
const path = yield* Path.Path
|
|
return path.resolve(outputPath)
|
|
}))
|
|
)
|
|
|
|
const visualize = Command.make("visualize", { outputDirectory }).pipe(
|
|
Command.withHandler(Effect.fnUntraced(function*({ outputDirectory }) {
|
|
const path = yield* Path.Path
|
|
const { fixtures, fixturesDir } = yield* Fixtures
|
|
const reporter = yield* Reporter
|
|
|
|
const paths = yield* Prompt.multiSelect({
|
|
message: "Select files whose bundle size you would like to visualize",
|
|
choices: fixtures.map((fixture) => ({
|
|
title: fixture,
|
|
value: path.join(fixturesDir, fixture)
|
|
}))
|
|
})
|
|
|
|
const report = yield* reporter.visualize({ paths, outputDirectory })
|
|
yield* Console.log(report)
|
|
}))
|
|
)
|
|
|
|
const reportPaths = Argument.file("paths", { mustExist: true }).pipe(
|
|
Argument.withDescription("Fixture files to include in the report"),
|
|
Argument.variadic({ min: 1 })
|
|
)
|
|
|
|
const report = Command.make("report", { paths: reportPaths }).pipe(
|
|
Command.withHandler(Effect.fnUntraced(function*({ paths }) {
|
|
const reporter = yield* Reporter
|
|
const report = yield* reporter.reportSelected({ paths })
|
|
yield* Console.log(report)
|
|
}))
|
|
)
|
|
|
|
const compareSelected = Command.make("compare-selected", { baseDirectory, paths: reportPaths }).pipe(
|
|
Command.withHandler(Effect.fnUntraced(function*({ baseDirectory, paths }) {
|
|
const reporter = yield* Reporter
|
|
const report = yield* reporter.reportSelectedComparison({ baseDirectory, paths })
|
|
yield* Console.log(report)
|
|
}))
|
|
)
|
|
|
|
const visualizeSelected = Command.make("visualize-selected", { outputDirectory, paths: reportPaths }).pipe(
|
|
Command.withHandler(Effect.fnUntraced(function*({ outputDirectory, paths }) {
|
|
const reporter = yield* Reporter
|
|
const report = yield* reporter.visualize({ outputDirectory, paths })
|
|
yield* Console.log(report)
|
|
}))
|
|
)
|
|
|
|
/**
|
|
* Bundle analysis CLI command with subcommands for comparing fixture bundle sizes, reporting selected fixtures, and generating visualizations.
|
|
*
|
|
* @category commands
|
|
* @since 4.0.0
|
|
*/
|
|
export const cli = Command.make("bundle").pipe(
|
|
Command.withSubcommands([compare, compareSelected, report, visualize, visualizeSelected])
|
|
)
|