UNPKG

sonda

Version:

Universal bundle analyzer and visualizer that works with most popular bundlers and frameworks.

480 lines (478 loc) 17.7 kB
import { DecodedSourceMap } from "@ampproject/remapping"; import { PluginOption } from "vite"; import { SourcesPathNormalizer } from "load-source-map"; import { Metafile, Plugin } from "esbuild"; import { Plugin as Plugin$1 } from "rollup"; import { Compiler } from "webpack"; //#region src/config.d.ts declare class Config implements Required<IntegrationOptions> { #private; constructor(options: Partial<IntegrationOptions> | Config, defaults: IntegrationOptions); clone(): Config; get enabled(): boolean; get include(): AssetFilter; get exclude(): AssetFilter; get format(): Format; get filename(): string; get outputDir(): string; get open(): boolean; get deep(): boolean; get sources(): boolean; get gzip(): boolean; get brotli(): boolean; get server(): boolean; get integration(): Integration; get sourcesPathNormalizer(): SourcesPathNormalizer; set filename(filename: string); set sourcesPathNormalizer(normalizer: SourcesPathNormalizer); } interface UserOptions { /** * Specifies whether the plugin is enabled. * * @default true */ enabled?: boolean; /** * Specifies a list of RegExp patterns used to match output assets to include in the report. * By default, all assets are included. * * Patterns are matched against the relative asset paths as displayed in the report. For example, * to include only JavaScript files, use `[ /\.js$/ ]`. * * @default null */ include?: AssetFilter; /** * Specifies a list of RegExp patterns used to match output assets to exclude from the report. * By default, no assets are excluded, except for those with `.map` and `.d.ts` extensions, which * are always excluded regardless of this setting. * * This option takes precedence over `include`. * * Patterns are matched against the relative asset paths as shown in the report. For example, to exclude all CSS files, use `[ /\.css$/ ]`. * * @default null */ exclude?: AssetFilter; /** * Specifies the output format of the report. Supported formats include: * * - `'html'` - An HTML file with a treemap visualization. * - `'json'` - A JSON file. * * @default 'html' */ format?: Format; /** * Specifies the filename of the generated report. If this value is an absolute path, * it overrides the `outputDir` option. * * The default value includes placeholders like `[index]` and `[env]`, which are replaced * during report generation. * * The `[index]` placeholder is replaced with a version number that increments each time * a new report is generated. This allows you to keep multiple revisions of the report without * overwriting previous ones. If you want to generate only a single report and always overwrite * the previous one, you can set this option to a static value, such as `'sonda'`. * * Additionally, framework integrations that can generate reports for both the client and server * (with the `server` option) will include the `[env]` placeholder in the filename. This is replaced with * the environment name (e.g., `client`, `server`), allowing you to distinguish between client and server reports. * * @default `'sonda_[index]'` for bundler integrations and `'sonda_[env]_[index]'` for framework integrations. */ filename?: string; /** * Specifies the directory where the report will be saved. This can be a relative or absolute path. By default, * the report is saved in a `.sonda` directory relative to the current working directory. * * The directory is created if it does not exist. * * @default '.sonda' */ outputDir?: string; /** * Specifies whether to automatically open the report in the default program for * the given file extension (`.html` or `.json`, depending on the `format` option) * after the build process. * * @default false */ open?: boolean; /** * Specifies whether to read source maps of imported modules. * * By default, external dependencies bundled into a single file appear as a single asset. When this option * is enabled, the report includes the source files of imported modules, if their source maps are available. * * Enabling this option may increase report generation time and reduce the accuracy of estimated GZIP * and Brotli sizes. * * @default false */ deep?: boolean; /** * Specifies whether to include source maps of generated assets in the report to visualize which parts of * the code contribute to the final asset size. * * ⚠️ * This option significantly increases the report size and embeds the **source code** of the assets. * If you are working with proprietary code, ensure you share the report responsibly. * ⚠️ * * @default false */ sources?: boolean; /** * Specifies whether to calculate asset sizes after compression with GZIP. * * The report also includes estimated compressed sizes for each file within an asset. These estimates are * approximate and intended for general reference. * * Enabling this option may increase report generation time. * * @default false */ gzip?: boolean; /** * Specifies whether to calculate asset sizes after compression with Brotli. * * The report also includes estimated compressed sizes for each file within an asset. These estimates are * approximate and intended for general reference. * * Enabling this option may increase report generation time. * * @default false */ brotli?: boolean; /** * Specifies whether to generate a report for the server build. * * This option is only available for framework integrations. * * @default false */ server?: boolean; } interface IntegrationOptions extends UserOptions { /** * Specifies the integration used to generate the report. */ integration: Integration; /** * Normalizes the paths in source maps to a consistent format. * * @default null */ sourcesPathNormalizer?: SourcesPathNormalizer; } /** * Filter for including or excluding assets based on their paths. */ type AssetFilter = Array<RegExp> | null; type Format = "html" | "json"; type Integration = "angular" | "astro" | "esbuild" | "next" | "nuxt" | "rolldown" | "rollup" | "rspack" | "sveltekit" | "vite" | "webpack" | "unknown"; //#endregion //#region src/integrations/esbuild.d.ts declare function SondaEsbuildPlugin(userOptions?: UserOptions): Plugin; declare function processEsbuildMetafile(metafile: Metafile, options: Config): Promise<void>; //#endregion //#region src/integrations/rollup.d.ts declare function SondaRollupPlugin(userOptions?: UserOptions): Plugin$1; //#endregion //#region src/integrations/vite.d.ts declare function SondaVitePlugin(userOptions?: UserOptions): PluginOption; //#endregion //#region src/integrations/webpack.d.ts declare class SondaWebpackPlugin { options: Config; constructor(userOptions?: UserOptions); apply(compiler: Compiler): void; } //#endregion //#region src/report/types.d.ts interface JsonReport { /** * Metadata about the report, including the version of Sonda used to generate it, * the integration used, and the options passed to Sonda. */ metadata: Metadata; /** * List of all input and output resources. */ resources: Array<Resource>; /** * List of all connections between resources. */ connections: Array<Connection>; /** * List of all detected external dependencies and their paths. If * a dependency has more than one path, it's likely duplicated and * bundled in multiple copies. */ dependencies: Array<Dependency>; /** * List of issues detected in the outputs. */ issues: Array<Issue>; /** * Partial source maps of the "asset" resources. * * This value is only available when the `deep` option is enabled. */ sourcemaps: Array<SourceMap>; } interface Metadata { /** * Version of Sonda used to generate the report. */ version: string; /** * Integration used to generate the report. */ integration: Integration; /** * The normalized value of the `sources` option passed to Sonda. */ sources: boolean; /** * The normalized value of the `gzip` option passed to Sonda. */ gzip: boolean; /** * The normalized value of the `brotli` option passed to Sonda. */ brotli: boolean; } /** * Base interface for all resources. * * Resources represent the following inputs: * * ┌─────────────────────────────┐ * │ │ * │ OPTIONAL ORIGINAL SOURCE │ * │ │ * └──────────────▲──────────────┘ * │ * │ * VIA SOURCEMAP * │ * │ * ┌─────────────────────────────┐ ┌──────────────┼──────────────┐ * │ │ │ │ * │ INTERNAL SOURCE │ │ EXTERNAL SOURCE │ * │ │ │ │ * └──────────────┬──────────────┘ └──────────────┬──────────────┘ * │ │ * │ │ * └─────────────────┬─────────────────┘ * │ * │ * ┌──────────────▼──────────────┐ * │ │ * │ BUNDLER │ * │ │ * └──────────────┬──────────────┘ * │ * │ * │ * │ * │ * ┌──────────────▼──────────────┐ * │ │ * │ ASSET │ * │ │ * └──────────────┬──────────────┘ * │ * │ * VIA SOURCEMAP * │ * │ * ┌──────────────▼──────────────┐ * │ │ * │ CHUNK │ * │ │ * └─────────────────────────────┘ */ interface ResourceBase { /** * Information where the resource comes from. */ kind: ResourceKind; /** * Relative path to the resource. * * If the `source` is `sourcemap`, the file may not exist in the filesystem. */ name: string; /** * Type of the resources, determined by the file extension. */ type: FileType; /** * Format of the module, if the resource type is `script`. */ format?: ModuleFormat; /** * Size of the resource without any compression. */ uncompressed: number; /** * Size of the resource after GZIP compression. * * This value is only available when the `gzip` option is enabled. */ gzip?: number; /** * Size of the resource after Brotli compression. * * This value is only available when the `brotli` option is enabled. */ brotli?: number; /** * Parent of the resource. * * If the `kind` is `chunk`, this resource is a part of the output * asset and value of `parent` is the name of the output asset. * * If the `kind` is `sourcemap`, this resource is a part of the source * map of other resource and value of `parent` is the name of that resource. */ parent?: string | Array<string> | null; } /** * Input resource loaded from the filesystem by the bundler. * * See INTERNAL SOURCE and EXTERNAL SOURCE in the diagram above. */ interface FilesystemResource extends ResourceBase { kind: "filesystem"; name: string; type: FileType; format: ModuleFormat; uncompressed: number; gzip?: never; brotli?: never; parent?: never; } /** * Input resource read from a sourcemap of the filesystem resource. * * See OPTIONAL ORIGINAL SOURCE in the diagram above. */ interface SourcemapResource extends ResourceBase { kind: "sourcemap"; name: string; type: FileType; format: ModuleFormat; uncompressed: number; gzip?: never; brotli?: never; parent: string | null; } /** * Output resource generated by the bundler. * * See ASSET in the diagram above. */ interface AssetResource extends ResourceBase { kind: "asset"; name: string; type: FileType; format?: never; uncompressed: number; gzip: number; brotli: number; parent?: never; } /** * Part of the input resource that was used in one of the assets * (after tree-shaking, minification, etc.). * * See CHUNK in the diagram above. */ interface ChunkResource extends ResourceBase { kind: "chunk"; name: string; type: FileType; format: ModuleFormat; uncompressed: number; gzip: number; brotli: number; parent: string; } interface Connection { kind: ConnectionKind; source: string; target: string; original: string | null; } interface Dependency { name: string; paths: Array<string>; } interface Issue { type: string; data: unknown; } /** * All types of resources. */ type Resource = FilesystemResource | SourcemapResource | AssetResource | ChunkResource; type Sizes = Required<Pick<ResourceBase, "uncompressed" | "gzip" | "brotli">>; type ResourceKind = "filesystem" | "sourcemap" | "asset" | "chunk"; type ConnectionKind = "entrypoint" | "import" | "require" | "dynamic-import" | "sourcemap"; type FileType = "component" | "font" | "image" | "script" | "style" | "other"; type ModuleFormat = "esm" | "cjs" | "amd" | "umd" | "iife" | "system" | "other"; /** * Type for the source map strings from the report after decoding. */ interface SourceMap { /** * Name of the asset file that the source map belongs to. */ name: string; /** * Stringified source map. * * Use the `DecodedMap` type for the decoded version of this map (after `JSON.parse()`). */ map: string; } type DecodedReportSourceMap = Pick<DecodedSourceMap, "mappings" | "sources" | "sourcesContent">; //#endregion //#region src/report/report.d.ts declare class Report { #private; readonly config: Config; readonly resources: Array<Resource>; readonly connections: Array<Connection>; readonly assets: Record<string, Array<string> | undefined>; protected metadata: Metadata; protected dependencies: Array<Dependency>; protected issues: Array<Issue>; protected sourcemaps: Array<SourceMap>; constructor(config: Config); addResource(resource: Resource): void; addConnection(connection: Connection): void; addAsset(name: string, entrypoints?: Array<string>): void; generate(): Promise<string>; addSourceMap(asset: string, sourcemap: DecodedReportSourceMap): void; } //#endregion //#region src/utils.d.ts /** * Normalizes a given path by removing leading null characters and converting it to a relative POSIX path. */ declare function normalizePath(pathToNormalize: string): string; /** * Returns the type of a given file based on its name. */ declare function getTypeByName(name: string): FileType; /** * Returns only the object keys which have a string value. */ //#endregion export { AssetResource, ChunkResource, Config, Connection, ConnectionKind, DecodedReportSourceMap, Dependency, FileType, FilesystemResource, Integration, IntegrationOptions, Issue, JsonReport, Metadata, ModuleFormat, Report, Resource, ResourceBase, ResourceKind, Sizes, SondaEsbuildPlugin, SondaRollupPlugin, SondaVitePlugin, SondaWebpackPlugin, SourceMap, SourcemapResource, UserOptions, getTypeByName, normalizePath, processEsbuildMetafile };