### Install esbuild plugin with yarn Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-esbuild/README.md Install the esbuild plugin using yarn. ```bash yarn add --dev @grafana/faro-esbuild-plugin ``` -------------------------------- ### Install esbuild plugin with npm Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-esbuild/README.md Install the esbuild plugin using npm. ```bash npm install --save-dev @grafana/faro-esbuild-plugin ``` -------------------------------- ### Install Faro CLI with npm Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Install the Faro CLI as a development dependency using npm. ```bash npm install --save-dev @grafana/faro-cli ``` -------------------------------- ### Install Faro CLI with yarn Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Install the Faro CLI as a development dependency using yarn. ```bash yarn add --dev @grafana/faro-cli ``` -------------------------------- ### Install Rollup/Vite Plugin with npm Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-rollup/README.md Install the Faro JavaScript Bundler Plugins for Rollup/Vite using npm. ```bash npm install --save-dev @grafana/faro-rollup-plugin ``` -------------------------------- ### Install Faro Webpack Plugin with npm Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-webpack/README.md Install the Faro Webpack plugin as a development dependency using npm. ```bash npm install --save-dev @grafana/faro-webpack-plugin ``` -------------------------------- ### Install Rollup/Vite Plugin with yarn Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-rollup/README.md Install the Faro JavaScript Bundler Plugins for Rollup/Vite using yarn. ```bash yarn add --dev @grafana/faro-rollup-plugin ``` -------------------------------- ### Install Faro Webpack Plugin with yarn Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-webpack/README.md Install the Faro Webpack plugin as a development dependency using yarn. ```bash yarn add --dev @grafana/faro-webpack-plugin ``` -------------------------------- ### Upload Source Maps with Faro CLI Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Upload source maps to the Faro API using the CLI. Ensure cURL is installed and available in your PATH. The CLI automatically finds and uploads all .map files in the specified output directory. ```bash npx faro-cli upload \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --output-path "./dist" \ --verbose ``` -------------------------------- ### Configure esbuild with Faro Plugin Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Use the `faroEsbuildPlugin` to automatically inject bundle IDs and upload source maps during the esbuild build process. Configure endpoint, API key, and other options as needed. ```javascript // build.js import * as esbuild from "esbuild"; import faroEsbuildPlugin from "@grafana/faro-esbuild-plugin"; await esbuild.build({ entryPoints: ["src/index.ts"], bundle: true, sourcemap: true, outdir: "dist", plugins: [ faroEsbuildPlugin({ appName: "my-esbuild-app", endpoint: "https://faro-collector-prod-us-east-0.grafana.net", apiKey: process.env.GRAFANA_API_KEY, appId: "abc123", stackId: "987654", gzipContents: false, // upload maps individually keepSourcemaps: false, verbose: true, recursive: true, // scan subdirectories of outdir outputPath: "dist", // explicit output directory (optional, auto-detected from outdir/outfile) }), ], }); // Expected: esbuild build injects bundleId banner, ensures all .map files have a `file` property, // then POSTs each *.js.map to the Faro API. Maps are deleted after successful upload. ``` -------------------------------- ### Configure Webpack with Authenticated Proxy Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-webpack/README.md If your proxy server requires authentication, include the username and password directly in the proxy URL within the FaroSourceMapUploaderPlugin configuration. ```javascript new FaroSourceMapUploaderPlugin({ // ... other options proxy: "http://username:password@proxy.example.com:8080", }), ``` -------------------------------- ### Upload Source Maps via Proxy Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Upload source maps through a proxy server. Use --proxy-user to provide authentication credentials if required. ```bash npx faro-cli upload \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --output-path "./dist" \ --proxy "your-proxy:port" \ --proxy-user "user:pass" \ --verbose ``` -------------------------------- ### Release New Version with Lerna Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/development/RELEASING.md Use this command to version and publish new releases. Ensure all changelogs are updated before running. ```bash npx lerna version --force-publish ``` -------------------------------- ### Upload Source Maps with Faro CLI Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/README.md Use this command to upload source maps to Faro. Set `skipUpload: true` in bundler plugin configuration to use this CLI command instead. Ensure all required parameters like endpoint, app-id, api-key, stack-id, and bundle-id are provided. ```bash npx faro-cli upload \ --endpoint "https://faro-collector-prod-us-east-0.grafana.net" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --output-path "./dist" \ --verbose ``` -------------------------------- ### Configure Webpack with FaroSourceMapUploaderPlugin Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/README.md Add this configuration to your webpack.config.js to integrate the Faro Webpack plugin. Provide your application's name, Faro sourcemap API URL, API key, application ID, and stack ID. The `gzipContents` option is set to true for compressed uploads. ```javascript // other imports import FaroSourceMapUploaderPlugin from "@grafana/faro-webpack-plugin"; module.exports = { // other configs plugins: [ // other plugins new FaroSourceMapUploaderPlugin({ appName: "$your-app-name", // this URL is different from the Faro Collector URL - find this value in the Frontend Observability plugin under "Settings" -> "Source Maps" tab endpoint: "$your-faro-sourcemap-api-url", apiKey: "$your-api-key", appId: "$your-app-id", stackId: "$your-stack-id", gzipContents: true, }), ], }; ``` -------------------------------- ### Configure Webpack with Proxy for Source Maps Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-webpack/README.md Use the `proxy` option in FaroSourceMapUploaderPlugin to route source map uploads through a specified proxy server. This is useful for environments with network restrictions. ```javascript new FaroSourceMapUploaderPlugin({ appName: "$your-app-name", endpoint: "$your-faro-collector-url", apiKey: "$your-api-key", appId: "$your-app-id", stackId: "$your-stack-id", proxy: "http://proxy.example.com:8080", gzipContents: true, }), ``` -------------------------------- ### Upload Source Maps with Gzip Payload Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/README.md Upload source maps using the Faro CLI with gzip payload compression enabled. This is useful for reducing upload size, especially for large source map files. The `--patterns` option can be used to specify which files to upload. ```bash npx faro-cli upload \ --endpoint "https://faro-collector-prod-us-east-0.grafana.net" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --output-path "./dist" \ --patterns "*.map" \ --gzip-payload \ --verbose ``` -------------------------------- ### Inject Bundle ID into JS Files Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Use this command to inject a bundle ID into all JavaScript files matching a pattern. Specify application name and file patterns. Verbose logging is optional. ```bash npx faro-cli inject-bundle-id \ --app-name "my-app" \ --files "dist/**/*.js" \ --verbose ``` -------------------------------- ### Configure esbuild with Faro plugin Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-esbuild/README.md Integrate the Faro esbuild plugin into your esbuild build configuration. Ensure you replace placeholder values with your actual application and API details. ```javascript import * as esbuild from 'esbuild'; import faroEsbuildPlugin from '@grafana/faro-esbuild-plugin'; await esbuild.build({ entryPoints: ['src/index.ts'], bundle: true, outdir: 'dist', plugins: [ faroEsbuildPlugin({ appName: "$your-app-name", // this URL is different from the Faro Collector URL - find this value in the Frontend Observability plugin under "Settings" -> "Source Maps" -> "Configure source map uploads" endpoint: "$your-faro-sourcemap-api-url", apiKey: "$your-api-key", appId: "$your-app-id", stackId: "$your-stack-id", gzipContents: true, }), ], }); ``` -------------------------------- ### Configure Webpack with FaroSourceMapUploaderPlugin Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-webpack/README.md Add the FaroSourceMapUploaderPlugin to your webpack.config.js to enable source map uploads. Ensure all required configuration values are provided. ```javascript // other imports import FaroSourceMapUploaderPlugin from "@grafana/faro-webpack-plugin"; module.exports = { // other configs plugins: [ // other plugins new FaroSourceMapUploaderPlugin({ appName: "$your-app-name", endpoint: "$your-faro-collector-url", apiKey: "$your-api-key", appId: "$your-app-id", stackId: "$your-stack-id", gzipContents: true, }), ], }; ``` -------------------------------- ### Upload Source Maps with Gzip Contents and Payload Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/README.md Combine both `--gzip-contents` and `--gzip-payload` options for maximum compression when uploading source maps with the Faro CLI. This compresses multiple source map files into a tarball and then compresses the HTTP payload. ```bash npx faro-cli upload \ --endpoint "$your-faro-collector-url" \ --app-id "$your-app-id" \ --api-key "$your-api-key" \ --stack-id "$your-stack-id" \ --bundle-id env \ --app-name "$your-app-name" \ --output-path "./dist" \ --patterns "*.map" \ --gzip-contents \ --gzip-payload \ --verbose ``` -------------------------------- ### Generate Curl Command with Proxy for Source Map Upload Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Generate a curl command for uploading source maps through a proxy server. Includes options for specifying proxy URL and authentication credentials. ```bash npx faro-cli curl \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --file "./dist/main.js.map" \ --proxy "http://proxy.example.com:8080" \ --proxy-user "username:password" ``` -------------------------------- ### Dry Run for Injecting Bundle ID Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Perform a dry run to preview which files would be modified by the inject-bundle-id command without making actual changes. This is useful for verification. ```bash npx faro-cli inject-bundle-id \ --bundle-id "your-bundle-id" \ --app-name "my-app" \ --files "dist/**/*.js" \ --dry-run \ --verbose ``` -------------------------------- ### Upload Source Maps using Faro CLI Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Upload source maps after the build process using the Faro CLI. This command reads bundle ID from environment variables when `--bundle-id env` is used. ```bash npx faro-cli upload \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id env \ --app-name "my-app" \ --output-path "./dist" \ --verbose ``` -------------------------------- ### Upload Source Maps with Gzip Contents and Payload Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Upload source maps using both gzip contents and gzip payload for maximum compression. Gzip contents compresses multiple source map files into a tarball before uploading, while gzip payload compresses the HTTP payload. ```bash npx faro-cli upload \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --output-path "./dist" \ --patterns "*.map" \ --gzip-contents \ --gzip-payload \ --verbose ``` -------------------------------- ### Generate Curl Command for Source Map Upload Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Generate a curl command to manually upload a source map file. Requires endpoint, application credentials, bundle ID, and the path to the source map file. ```bash npx faro-cli curl \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --file "./dist/main.js.map" ``` -------------------------------- ### Configure FaroSourceMapUploaderPlugin for Webpack Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Use this Webpack plugin to upload source maps and inject a bundle ID banner. Configure options like appName, endpoint, apiKey, appId, and stackId. Supports features like gzip compression, custom CDN paths, and recursive scanning. ```javascript // webpack.config.js import FaroSourceMapUploaderPlugin from "@grafana/faro-webpack-plugin"; module.exports = { mode: "production", devtool: "source-map", output: { path: path.resolve(__dirname, "dist") }, plugins: [ new FaroSourceMapUploaderPlugin({ appName: "my-frontend-app", // required: matches Faro Web SDK appName endpoint: "https://faro-collector-prod-us-east-0.grafana.net", // required: sourcemap API URL (not collector URL) apiKey: process.env.GRAFANA_API_KEY, // required: Grafana Cloud access token appId: "abc123", // required: matches Faro Web SDK appId stackId: "987654", // required: Grafana Cloud stack ID gzipContents: true, // compress source maps into tarballs before upload (default: false) keepSourcemaps: false, // delete source maps from dist after upload (default: false) verbose: true, // log upload progress (default: false) bundleId: "release-1.2.3", // optional: custom build ID (auto-generated if omitted) outputFiles: /main\.\w+\.js\.map$/, // optional: regex to filter which maps to upload maxUploadSize: 30 * 1024 * 1024, // optional: per-upload size limit in bytes (default: 30MB) recursive: false, // optional: scan subdirectories (default: false) proxy: "http://proxy.corp.example.com:3128", // optional: proxy for upload requests nextjs: true, // optional: prepend "_next/" to source map file property (Webpack only) prefixPath: "static/js/", // optional: custom prefix for CDN-hosted assets prefixPathBasenameOnly: false, // optional: strip directory before prepending prefix }), ], }; // Expected: after `webpack --mode production`, all *.js.map files in dist/ are uploaded, // then deleted. Each JS bundle begins with: // (function(){try{var g=...;g["__faroBundleId_my-frontend-app"]="release-1.2.3"}catch(l){}})(); ``` -------------------------------- ### Generate Gzipped Curl Command for Source Map Upload Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Generate a curl command for uploading source maps with gzip compression enabled. This can reduce upload size and time. ```bash npx faro-cli curl \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --file "./dist/main.js.map" \ --gzip-payload ``` -------------------------------- ### Configure faroUploader for Rollup/Vite Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt This factory function configures a Rollup/Vite plugin to prepend the bundle ID snippet and upload source maps. Use `skipUpload` to defer uploads and `prefixPath` for CDN configurations. ```javascript // vite.config.js (or rollup.config.js with export default) import { defineConfig } from "vite"; import faroUploader from "@grafana/faro-rollup-plugin"; export default defineConfig(({ mode }) => ({ build: { sourcemap: true }, plugins: [ faroUploader({ appName: "my-vite-app", endpoint: "https://faro-collector-prod-us-east-0.grafana.net", apiKey: process.env.GRAFANA_API_KEY, appId: "abc123", stackId: "987654", gzipContents: true, keepSourcemaps: false, verbose: true, prefixPath: "assets/", // prepend "assets/" to source map `file` property for CDN paths prefixPathBasenameOnly: true, // strip directory, so "assets/chunk-abc.js" not "assets/src/chunk-abc.js" skipUpload: mode !== "production", // skip upload in non-production builds }), ], })); // Expected: rollup/vite build injects bundleId into each JS chunk, then uploads .map files. // If skipUpload: true, writes bundleId to .env.MY_VITE_APP for later CLI upload. ``` -------------------------------- ### Configure Rollup/Vite Plugin Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-rollup/README.md Add the Faro uploader plugin to your Rollup or Vite configuration file. Ensure you obtain the correct `endpoint`, `apiKey`, `appId`, and `stackId` from the Grafana Cloud Frontend Observability plugin's 'Settings' -> 'Source Maps' tab. ```javascript // other imports import faroUploader from '@grafana/faro-rollup-plugin'; export default defineConfig(({ mode }) => { return { // other configs plugins: [ // other plugins faroUploader({ appName: "$your-app-name", // this URL is different from the Faro Collector URL - find this value in the Frontend Observability plugin under "Settings" -> "Source Maps" -> "Configure source map uploads" endpoint: "$your-faro-sourcemap-api-url", apiKey: "$your-api-key", appId: "$your-app-id", stackId: "$your-stack-id", gzipContents: true, }), ], }; ``` -------------------------------- ### Ensure Source Map File Properties Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Scans a build output directory to ensure all `.map` files have a `file` property, which is critical for bundlers like Turbopack. ```typescript import { ensureSourceMapFileProperties } from "@grafana/faro-bundlers-shared"; // Fix missing "file" properties in all source maps in the dist directory ensureSourceMapFileProperties( "./dist", // output directory to scan true, // verbose: log each file processed true // recursive: also scan subdirectories ); // [Faro] Set file property on source map: abc123.js.map -> file: xyz789.js // [Faro] Added file property to source map: main.js.map -> file: main.js ``` -------------------------------- ### Generate cURL Command for Source Map Upload Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt The `faro-cli curl` command generates a cURL command for uploading a single source map file, useful for manual uploads or debugging authentication. It supports plain or gzip-compressed payloads. ```bash # Generate a plain cURL command npx @grafana/faro-cli curl \ --endpoint "https://faro-collector-prod-us-east-0.grafana.net" \ --app-id "abc123" \ --api-key "$GRAFANA_API_KEY" \ --stack-id "987654" \ --bundle-id "release-1.2.3" \ --file "./dist/main.js.map" ``` ```bash # Generate a gzip-compressed cURL command npx @grafana/faro-cli curl \ --endpoint "https://faro-collector-prod-us-east-0.grafana.net" \ --app-id "abc123" \ --api-key "$GRAFANA_API_KEY" \ --stack-id "987654" \ --bundle-id "release-1.2.3" \ --file "./dist/main.js.map" \ --gzip-payload ``` -------------------------------- ### Configure Rollup/Vite Plugin for Faro Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/README.md Add this snippet to your `rollup.config.js` or `vite.config.js` to integrate the Faro uploader plugin. Ensure the `endpoint`, `apiKey`, `appId`, and `stackId` are correctly configured for your Grafana Cloud instance. ```javascript // other imports import faroUploader from '@grafana/faro-rollup-plugin'; export default defineConfig(({ mode }) => { return { // other configs plugins: [ // other plugins faroUploader({ appName: "$your-app-name", // this URL is different from the Faro Collector URL - find this value in the Frontend Observability plugin under "Settings" -> "Source Maps" tab endpoint: "$your-faro-sourcemap-api-url", apiKey: "$your-api-key", appId: "$your-app-id", stackId: "$your-stack-id", gzipContents: true, }), ], }; }); ``` -------------------------------- ### Rollup Plugin Configuration for Source Maps Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Configure the Faro Rollup plugin to skip uploading source maps during the build process. The `skipUpload: true` option defers this to the CLI. ```javascript // rollup.config.js import faroUploader from '@grafana/faro-rollup-plugin'; export default { // ... other rollup config plugins: [ // ... other plugins faroUploader({ // this URL is different from the Faro Collector URL - find this value in the Frontend Observability plugin under "Settings" -> "Source Maps" -> "Configure source map uploads" endpoint: 'https://faro-api-prod-us-east-0.grafana.net/faro/api/v1', appName: 'my-app', appId: 'your-app-id', apiKey: 'your-api-key', stackId: 'your-stack-id', skipUpload: true, // Skip uploading during build verbose: true, }), ], }; ``` -------------------------------- ### Generate Curl Command for Source Maps Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/README.md Use this command to generate a curl command for uploading source maps. Ensure you replace placeholder values with your actual endpoint, app ID, API key, stack ID, bundle ID, and file path. ```bash npx faro-cli curl \ --endpoint "https://faro-collector-prod-us-east-0.grafana.net" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --file "./dist/main.js.map" ``` -------------------------------- ### Inject Bundle ID into JavaScript Files Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt The `faro-cli inject-bundle-id` command prepends the Faro `bundleId` snippet to JavaScript files. This is useful for projects not using bundlers or for post-build injection. It supports specifying a bundle ID, generating a random one, or performing a dry run. ```bash # Inject a specific bundle ID into all JS files npx @grafana/faro-cli inject-bundle-id \ --bundle-id "release-1.2.3" \ --app-name "my-app" \ --files "dist/**/*.js" \ --verbose ``` ```bash # Generate a random bundle ID and inject it (exports bundleId to .env.MY_APP) npx @grafana/faro-cli inject-bundle-id \ --app-name "my-app" \ --files "dist/main.js" "dist/vendor.js" \ --verbose ``` ```bash # Dry run — show which files would be modified without changing them npx @grafana/faro-cli inject-bundle-id \ --bundle-id "release-1.2.3" \ --app-name "my-app" \ --files "dist/**/*.js" \ --dry-run \ --verbose ``` -------------------------------- ### FaroSourceMapUploaderPlugin (Webpack) Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt A Webpack plugin that injects a bundleId banner into JS chunks and uploads source maps after the build. It supports various options for customization, including Next.js prefix handling and custom CDN paths. ```APIDOC ## FaroSourceMapUploaderPlugin (Webpack) ### Description A Webpack plugin class that injects a `bundleId` banner into all emitted JS chunks and uploads source maps to the Faro source map API after the build completes. Supports Next.js `_next/` prefix handling via the `nextjs` option and custom CDN prefix paths via `prefixPath`. ### Configuration Options - **appName** (string) - Required - Matches Faro Web SDK appName. - **endpoint** (string) - Required - Sourcemap API URL (not collector URL). - **apiKey** (string) - Required - Grafana Cloud access token. - **appId** (string) - Required - Matches Faro Web SDK appId. - **stackId** (string) - Required - Grafana Cloud stack ID. - **gzipContents** (boolean) - Optional - Compress source maps into tarballs before upload (default: false). - **keepSourcemaps** (boolean) - Optional - Delete source maps from dist after upload (default: false). - **verbose** (boolean) - Optional - Log upload progress (default: false). - **bundleId** (string) - Optional - Custom build ID (auto-generated if omitted). - **outputFiles** (RegExp) - Optional - Regex to filter which maps to upload. - **maxUploadSize** (number) - Optional - Per-upload size limit in bytes (default: 30MB). - **recursive** (boolean) - Optional - Scan subdirectories (default: false). - **proxy** (string) - Optional - Proxy for upload requests. - **nextjs** (boolean) - Optional - Prepend `_next/` to source map file property (Webpack only). - **prefixPath** (string) - Optional - Custom prefix for CDN-hosted assets. - **prefixPathBasenameOnly** (boolean) - Optional - Strip directory before prepending prefix. ### Example Usage ```javascript // webpack.config.js import FaroSourceMapUploaderPlugin from "@grafana/faro-webpack-plugin"; module.exports = { mode: "production", devtool: "source-map", output: { path: path.resolve(__dirname, "dist") }, plugins: [ new FaroSourceMapUploaderPlugin({ appName: "my-frontend-app", endpoint: "https://faro-collector-prod-us-east-0.grafana.net", apiKey: process.env.GRAFANA_API_KEY, appId: "abc123", stackId: "987654", gzipContents: true, keepSourcemaps: false, verbose: true, bundleId: "release-1.2.3", outputFiles: /main\.\w+\.js\.map$/, maxUploadSize: 30 * 1024 * 1024, recursive: false, proxy: "http://proxy.corp.example.com:3128", nextjs: true, prefixPath: "static/js/", prefixPathBasenameOnly: false, }), ], }; ``` ### Expected Outcome After running `webpack --mode production`, all `*.js.map` files in the `dist/` directory are uploaded and then deleted. Each JS bundle will be prepended with a `bundleId` snippet. ``` -------------------------------- ### Inject Bundle ID into JavaScript Files Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Inject a bundle ID into JavaScript files that do not already contain it. This command locates files matching glob patterns and prepends the bundle ID snippet. ```bash npx faro-cli inject-bundle-id \ --bundle-id "your-bundle-id" \ --app-name "your-app-name" \ --files "dist/**/*.js" \ --verbose ``` -------------------------------- ### faroUploader (Rollup / Vite) Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt A factory function for Rollup/Vite plugins that uses `renderChunk` to prepend the bundleId snippet and `writeBundle` to upload source maps. Vite users configure it within `defineConfig`. ```APIDOC ## faroUploader (Rollup / Vite) ### Description A Rollup/Vite plugin factory function. Uses the `renderChunk` hook to prepend the `bundleId` snippet and the `writeBundle` hook to upload source maps. Vite users configure it identically inside `defineConfig`. ### Configuration Options - **appName** (string) - Required - Matches Faro Web SDK appName. - **endpoint** (string) - Required - Sourcemap API URL (not collector URL). - **apiKey** (string) - Required - Grafana Cloud access token. - **appId** (string) - Required - Matches Faro Web SDK appId. - **stackId** (string) - Required - Grafana Cloud stack ID. - **gzipContents** (boolean) - Optional - Compress source maps into tarballs before upload (default: false). - **keepSourcemaps** (boolean) - Optional - Delete source maps from dist after upload (default: false). - **verbose** (boolean) - Optional - Log upload progress (default: false). - **prefixPath** (string) - Optional - Prepend `prefixPath` to source map `file` property for CDN paths. - **prefixPathBasenameOnly** (boolean) - Optional - Strip directory, so `assets/chunk-abc.js` not `assets/src/chunk-abc.js`. - **skipUpload** (boolean) - Optional - Skip upload in non-production builds. ### Example Usage ```javascript // vite.config.js (or rollup.config.js with export default) import { defineConfig } from "vite"; import faroUploader from "@grafana/faro-rollup-plugin"; export default defineConfig(({ mode }) => ({ build: { sourcemap: true }, plugins: [ faroUploader({ appName: "my-vite-app", endpoint: "https://faro-collector-prod-us-east-0.grafana.net", apiKey: process.env.GRAFANA_API_KEY, appId: "abc123", stackId: "987654", gzipContents: true, keepSourcemaps: false, verbose: true, prefixPath: "assets/", prefixPathBasenameOnly: true, skipUpload: mode !== "production", }), ], })); ``` ### Expected Outcome Rollup/Vite build injects `bundleId` into each JS chunk, then uploads `.map` files. If `skipUpload` is true, it writes `bundleId` to `.env.MY_VITE_APP` for later CLI upload. ``` -------------------------------- ### Webpack Plugin Configuration for Source Maps Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Configure the Faro Webpack plugin to skip uploading source maps during the build. Set `skipUpload: true` to enable CLI-based uploads later. ```javascript // webpack.config.js const FaroSourceMapUploaderPlugin = require('@grafana/faro-webpack-plugin'); module.exports = { // ... other webpack config plugins: [ // ... other plugins new FaroSourceMapUploaderPlugin({ endpoint: 'https://faro-api-prod-us-east-0.grafana.net/faro/api/v1', appName: 'my-app', appId: 'your-app-id', apiKey: 'your-api-key', stackId: 'your-stack-id', skipUpload: true, // Skip uploading during build verbose: true, }), ], }; ``` -------------------------------- ### Generate Curl Command with Gzip Compression Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/README.md This command generates a curl command that includes gzip compression for the payload, which can be more efficient for larger files. Replace placeholder values as needed. ```bash npx faro-cli curl \ --endpoint "https://faro-collector-prod-us-east-0.grafana.net" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --file "./dist/main.js.map" \ --gzip-payload ``` -------------------------------- ### Modify Source Map File Property Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Prepends a prefix string to the `file` property of a source map. Useful for assets served from a CDN subdirectory. ```typescript import { modifySourceMapFileProperty, normalizePrefix } from "@grafana/faro-bundlers-shared"; // Prepend "assets/" to the file property of a single source map modifySourceMapFileProperty( "./dist/assets/main.abc123.js.map", // path to the source map file "assets/", // prefix to prepend (normalized to ensure trailing slash) true, // verbose false // basenameOnly: false = keep full path, true = only filename ); // [Faro] Modified source map file property: main.abc123.js.map -> assets/main.abc123.js // normalizePrefix ensures trailing slash console.log(normalizePrefix("assets")); // → "assets/" console.log(normalizePrefix("assets/")); // → "assets/" ``` -------------------------------- ### Export Bundle ID to File Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Writes the bundle ID to a `.env.` file. This is used when `skipUpload: true` or by the `inject-bundle-id` CLI command. ```typescript import { exportBundleIdToFile } from "@grafana/faro-bundlers-shared"; // Writes "FARO_BUNDLE_ID_MY_APP=release-1.2.3\n" to ./.env.MY_APP exportBundleIdToFile("release-1.2.3", "my-app", true); // [Faro] Exported bundleId release-1.2.3 to file /project/.env.MY_APP // Later in CI, the CLI reads it back: // npx faro-cli upload --bundle-id env --app-name "my-app" ... ``` -------------------------------- ### Upload Source Maps with Gzip Payload Source: https://github.com/grafana/faro-javascript-bundler-plugins/blob/main/packages/faro-cli/README.md Upload source maps with gzip payload enabled for reduced upload size. This option compresses the HTTP payload itself using gzip content encoding. ```bash npx faro-cli upload \ --endpoint "your-faro-sourcemap-api-url" \ --app-id "your-app-id" \ --api-key "your-api-key" \ --stack-id "your-stack-id" \ --bundle-id "your-bundle-id" \ --output-path "./dist" \ --patterns "*.map" \ --gzip-payload \ --verbose ``` -------------------------------- ### Generate Faro Bundle ID Snippet Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Generates an IIFE to set a global `__faroBundleId_` variable. Useful for injecting build identity into runtime bundles. ```typescript import { faroBundleIdSnippet, cleanAppName } from "@grafana/faro-bundlers-shared"; const snippet = faroBundleIdSnippet("release-1.2.3", "my-frontend-app"); console.log(snippet); // Output (single line, minified IIFE): // (function(){try{var g=typeof window!=="undefined"?window:typeof global!=="undefined"?global:typeof self!=="undefined"?self:{};g["__faroBundleId_my-frontend-app"]="release-1.2.3"}catch(l){}})(); // cleanAppName normalizes app names for use in env var names console.log(cleanAppName("my-frontend-app")); // → "MY_FRONTEND_APP" console.log(cleanAppName("My App v2")); // → "MY_APP_V2" ``` -------------------------------- ### Determine if a file should be processed Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Use `shouldProcessFile` to check if a filename matches the JS source map pattern and optionally filter against an allowlist or regex. It requires the filename and an optional allowlist (array of strings or regex). ```typescript import { shouldProcessFile, JS_SOURCEMAP_PATTERN } from "@grafana/faro-bundlers-shared"; // JS_SOURCEMAP_PATTERN = /\.(js|ts|jsx|tsx|mjs|cjs)\.map$/ shouldProcessFile("main.js.map", undefined); // → true (no filter) shouldProcessFile("main.js.map", ["main.js"]); // → true (array: checks for "main.js.map") shouldProcessFile("vendor.js.map", ["main.js"]); // → false (not in allowlist) shouldProcessFile("main.js.map", /main\.\w+\.js\.map$/); // → true (regex match) shouldProcessFile("style.css.map", undefined); // → false (not a JS source map) shouldProcessFile("image.png", undefined); // → false (not a source map at all) ``` -------------------------------- ### Validate Proxy URL Source: https://context7.com/grafana/faro-javascript-bundler-plugins/llms.txt Validates proxy URL strings for upload requests, rejecting invalid schemes or missing hostnames. Called automatically by `uploadSourceMap` and `uploadCompressedSourceMaps`. ```typescript import { validateProxyUrl } from "@grafana/faro-bundlers-shared"; try { validateProxyUrl("http://proxy.corp.example.com:3128"); // ✓ valid validateProxyUrl("http://user:pass@proxy.corp.example.com:8080"); // ✓ valid with auth validateProxyUrl("ftp://proxy.example.com"); // ✗ throws: must start with http:// or https:// validateProxyUrl("javascript:alert(1)"); // ✗ throws: contains invalid scheme: javascript: validateProxyUrl(""); // ✗ throws: must be a non-empty string } catch (err) { console.error(err.message); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.