UNPKG

@codecov/bundle-analyzer

Version:

Official Codecov Bundle Analyzer

1 lines 12.9 kB
{"version":3,"file":"index.mjs","sources":["../src/version.ts","../src/options.ts","../src/assets.ts","../src/index.ts"],"sourcesContent":["// rollup will replace these during the build. If not defined (e.g., in tests), fall back to defaults.\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nexport const PLUGIN_NAME: string =\n // @ts-expect-error - value replaced by rollup\n typeof __PACKAGE_NAME__ !== \"undefined\"\n ? // @ts-expect-error - value replaced by rollup\n __PACKAGE_NAME__\n : \"@codecov/bundle-analyzer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nexport const PLUGIN_VERSION: string =\n // @ts-expect-error - value replaced by rollup\n typeof __PACKAGE_VERSION__ !== \"undefined\" ? __PACKAGE_VERSION__ : \"0.0.0\";\n","import { type Output } from \"@codecov/bundler-plugin-core\";\n\n/** Configuration options for the bundle-analyzer analyzer. */\nexport interface BundleAnalyzerOptions {\n /**\n * Asynchronous function to customize the report output.\n *\n * This function allows you to modify the report output before it is finalized. By default, it\n * returns the original output without modification.\n *\n * @returns {Promise<Output>} A promise that resolves to the customized output.\n */\n beforeReportUpload?: (original: Output) => Promise<Output>;\n\n /**\n * Patterns to ignore certain files or directories in the analysis. The patterns follow the\n * standard glob pattern syntax. By default, it returns an empty list.\n */\n ignorePatterns?: string[];\n\n /**\n * A pattern to normalize asset names (e.g., for hashing). By default, it returns an empty string,\n * which will replace anything \"hashlike\" with \"*\".\n */\n normalizeAssetsPattern?: string;\n}\n\n/* defaultBundleAnalyzerOptions are default implementations for `BundleAnalyzerOptions` */\nconst defaultBundleAnalyzerOptions: Required<BundleAnalyzerOptions> = {\n // eslint-disable-next-line @typescript-eslint/require-await\n beforeReportUpload: async (original: Output): Promise<Output> => original,\n ignorePatterns: [],\n normalizeAssetsPattern: \"\",\n};\n\n/* normalizeBundleAnalyzerOptions fills in missing bundle-analyzer options with default values */\nexport function normalizeBundleAnalyzerOptions(\n options: Partial<BundleAnalyzerOptions> = {},\n): Required<BundleAnalyzerOptions> {\n return {\n ...defaultBundleAnalyzerOptions,\n ...options,\n };\n}\n\nexport type NormalizedBundleAnalyzerOptions = Required<BundleAnalyzerOptions>;\n","import path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport {\n getCompressedSize,\n normalizePath,\n type Asset,\n} from \"@codecov/bundler-plugin-core\";\nimport micromatch from \"micromatch\";\n\n/* getAssets gets assets from the starting paths to include in a bundle stats report */\nexport const getAssets = async (\n buildDirectoryPaths: string[],\n ignorePatterns: string[] = [],\n normalizeAssetsPattern = \"\",\n): Promise<Asset[]> => {\n const allAssets = await Promise.all(\n buildDirectoryPaths.map(async (buildDirectoryPath) => {\n const absoluteAssetsDir = path.resolve(buildDirectoryPath);\n const files = await listChildFilePaths(absoluteAssetsDir);\n\n // apply filtering only if ignorePatterns contains patterns\n const filteredFiles = ignorePatterns.length\n ? files.filter(\n (file) =>\n !micromatch.isMatch(file, ignorePatterns, {\n dot: true,\n matchBase: true,\n }),\n )\n : files;\n\n const assets: Asset[] = await Promise.all(\n filteredFiles.map((file: string) =>\n getAsset(file, absoluteAssetsDir, normalizeAssetsPattern),\n ),\n );\n\n return assets;\n }),\n );\n\n return allAssets.flat();\n};\n\n/* getAsset gets an Asset that can be included in a bundle stats report */\nexport const getAsset = async (\n filePath: string,\n parentPath: string,\n normalizeAssetsPattern: string,\n): Promise<Asset> => {\n const fileName = path.relative(parentPath, filePath);\n const fileContents = await fs.readFile(filePath);\n const size = fileContents.byteLength;\n const gzipSize = await getCompressedSize({ fileName, code: fileContents });\n\n // normalize the file name if a pattern is provided. By default (when pattern is \"\"), this\n // will replace anything \"hashlike\" with *. For example index-1dca144e.js --> index-*.js\n const normalizedName = normalizePath(\n fileName,\n normalizeAssetsPattern,\n \"bundle-analyzer\",\n );\n\n return {\n name: fileName,\n size: size,\n gzipSize: gzipSize,\n normalized: normalizedName,\n };\n};\n\n/* listChildFilePaths lists the subdirectory file paths within a given directory path */\nexport const listChildFilePaths = async (\n directoryPath: string,\n): Promise<string[]> => {\n const results: string[] = [];\n const list = await fs.readdir(directoryPath, {\n withFileTypes: true,\n });\n\n for (const file of list) {\n const fullPath = path.join(directoryPath, file.name);\n\n if (file.isDirectory()) {\n const childPaths = await listChildFilePaths(fullPath);\n childPaths.forEach((childFile) => results.push(childFile));\n } else if (file.isFile()) {\n results.push(fullPath);\n }\n }\n\n return results;\n};\n","import {\n normalizeOptions,\n Output,\n type Options,\n type NormalizedOptions,\n} from \"@codecov/bundler-plugin-core\";\nimport { PLUGIN_NAME, PLUGIN_VERSION } from \"./version\";\nimport {\n normalizeBundleAnalyzerOptions,\n type NormalizedBundleAnalyzerOptions,\n type BundleAnalyzerOptions,\n} from \"./options\";\nimport { getAssets } from \"./assets\";\n\nexport { type Options } from \"@codecov/bundler-plugin-core\";\nexport { type BundleAnalyzerOptions } from \"./options\";\n\n/**\n * Generates a Codecov bundle stats report and optionally uploads it to Codecov. This function can\n * be imported into your code or used via the bundle-analyzer CLI.\n *\n * @param {string[]} buildDirectoryPaths - The path(s) to the build directory or directories\n * containing the production assets for the report. Can be absolute or relative.\n * @param {Options} coreOptions - Configuration options for generating and uploading the report.\n * @param {BundleAnalyzerOptions} [bundleAnalyzerOptions] - Optional configuration for\n * bundle-analyzer usage.\n *\n * @returns {Promise<string>} A promise that resolves when the report is generated and uploaded\n * (dry-runned or uploaded).\n *\n * @example\n * const buildDirs = ['/path/to/build/directory', '/path/to/another/build']; // absolute or relative paths\n * const coreOpts = {\n * dryRun: true,\n * uploadToken: 'your-upload-token',\n * retryCount: 3,\n * apiUrl: 'https://api.codecov.io',\n * bundleName: 'my-bundle', // bundle identifier in Codecov\n * enableBundleAnalysis: true,\n * debug: true,\n * };\n * const bundleAnalyzerOpts = {\n * beforeReportUpload: async (original) => original,\n * ignorePatterns: [\"*.map\"],\n * normalizeAssetsPattern: \"[name]-[hash].js\",\n * };\n *\n * createAndUploadReport(buildDirs, coreOpts, bundleAnalyzerOpts)\n * .then(() => console.log('Report successfully generated and uploaded.'))\n * .catch((error) => console.error('Failed to generate or upload report:', error));\n */\nexport const createAndUploadReport = async (\n buildDirectoryPaths: string[],\n coreOptions: Options,\n bundleAnalyzerOptions?: BundleAnalyzerOptions,\n): Promise<string> => {\n const coreOpts = normalizeOptions(coreOptions);\n if (!coreOpts.success) {\n throw new Error(\"Invalid options: \" + coreOpts.errors.join(\" \"));\n }\n const bundleAnalyzerOpts = normalizeBundleAnalyzerOptions(\n bundleAnalyzerOptions,\n );\n\n const initialReport = await createReport(\n buildDirectoryPaths,\n coreOpts.options,\n bundleAnalyzerOpts,\n );\n\n // Override report as needed (by default returns unchanged)\n let finalReport: Output;\n try {\n finalReport = await bundleAnalyzerOpts.beforeReportUpload(initialReport);\n } catch (error) {\n throw new Error(`Error in beforeReportUpload: ${error}`);\n }\n\n if (!coreOptions.dryRun) {\n await finalReport.write(true);\n }\n\n return finalReport.bundleStatsToJson();\n};\n\n/* createReport creates the output bundle stats report */\nconst createReport = async (\n buildDirectoryPaths: string[],\n normalizedCoreOptions: NormalizedOptions,\n normalizedBundleAnalyzerOptions: NormalizedBundleAnalyzerOptions,\n): Promise<Output> => {\n // initialize report\n const output: Output = new Output(normalizedCoreOptions, {\n metaFramework: \"bundle-analyzer\",\n });\n output.start();\n output.setPlugin(PLUGIN_NAME, PLUGIN_VERSION);\n\n // handle assets\n output.assets = await getAssets(\n buildDirectoryPaths,\n normalizedBundleAnalyzerOptions.ignorePatterns,\n normalizedBundleAnalyzerOptions.normalizeAssetsPattern,\n );\n\n // handle chunks and modules (not supported at this time)\n output.chunks = [];\n output.modules = [];\n\n // close and return report\n output.end();\n return output;\n};\n"],"names":[],"mappings":"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"}