### Install @relative-ci/webpack-plugin Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Install the plugin as a development dependency using your preferred package manager. ```bash npm install --save-dev @relative-ci/webpack-plugin ``` ```bash yarn add --dev @relative-ci/webpack-plugin ``` ```bash pnpm add -D @relative-ci/webpack-plugin ``` -------------------------------- ### Install dependencies for Create React App Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Install the required packages to customize the Create React App webpack configuration. ```bash npm install --dev customize-cra react-app-rewired ``` ```bash yarn add --dev customize-cra react-app-rewired ``` ```bash pnpm add -D customize-cra react-app-rewired ``` -------------------------------- ### Define dependencies in package.json Source: https://relative-ci.com/documentation/guides/identify-and-fix-bundle-npm-duplicate-dependencies Example configuration showing dependencies that may lead to version conflicts. ```json { "name": "example-app", // ... package information "dependencies": { "@ant-design": "4.7.0", "antd": "4.24.14" } } ``` -------------------------------- ### Install bundle-stats filter plugin Source: https://relative-ci.com/documentation/guides/bundle-stats/webpack-stats-plugin Install the filter plugin to optimize the size of the generated stats JSON file. ```bash npm install --save-dev @bundle-stats/plugin-webpack-filter ``` ```bash yarn add --dev @bundle-stats/plugin-webpack-filter ``` ```bash pnpm add -D @bundle-stats/plugin-webpack-filter ``` -------------------------------- ### Vite Build Output Example Source: https://relative-ci.com/documentation/guides/vite-config Sample console output from running a Vite 5 production build. ```bash npm run build vite build vite v5.0.0 building for production... ✓ 1862 modules transformed. dist/index.html 0.31 kB │ gzip: 0.22 kB dist/assets/utils.8L8ZNlhE.css 0.03 kB │ gzip: 0.05 kB dist/assets/index._deYuKRK.css 546.34 kB │ gzip: 66.79 kB dist/assets/repo-list.KTrC4ioP.js 0.55 kB │ gzip: 0.38 kB dist/assets/CloseOutlined.Ac2Sglwr.js 0.66 kB │ gzip: 0.47 kB dist/assets/col.KPyWUTbA.js 4.48 kB │ gzip: 1.84 kB dist/assets/utils.pw5xtUsQ.js 40.12 kB │ gzip: 13.12 kB dist/assets/about._IcwKZoH.js 79.56 kB │ gzip: 26.66 kB dist/assets/repo-details.O1eeDOyK.js 117.49 kB │ gzip: 36.84 kB dist/assets/index.rdoY6xeT.js 414.28 kB │ gzip: 136.95 kB ✓ built in 2.94s ``` -------------------------------- ### Install @relative-ci/cli Source: https://relative-ci.com/documentation/setup/agent/cli Install the CLI package as a development dependency using your preferred package manager. ```bash npm install --save-dev @relative-ci/cli ``` ```bash yarn add --dev @relative-ci/cli ``` ```bash pnpm add -D @relative-ci/cli ``` -------------------------------- ### Install rollup-plugin-webpack-stats Source: https://relative-ci.com/documentation/guides/bundle-stats/vite Commands to install the plugin using npm, yarn, or pnpm. ```bash npm install --save-dev rollup-plugin-webpack-stats ``` ```bash yarn add --dev rollup-plugin-webpack-stats ``` ```bash pnpm add -D rollup-plugin-webpack-stats ``` -------------------------------- ### Install webpack-stats-plugin Source: https://relative-ci.com/documentation/guides/bundle-stats/webpack-stats-plugin Install the plugin as a development dependency using npm, yarn, or pnpm. ```bash npm install --save-dev webpack-stats-plugin ``` ```bash yarn add --dev webpack-stats-plugin ``` ```bash pnpm add -D webpack-stats-plugin ``` -------------------------------- ### Example Webpack 5 build output Source: https://relative-ci.com/documentation/guides/webpack-config Sample output showing assets generated with content hashes in Webpack 5. ```text assets by path *.js 10.5 KiB asset vendors.f1eef34c98603711f45e.js 8.71 KiB [emitted] [immutable] [minimized] (name: vendors) (id hint: vendors) asset main.7c920d907e4c753d0935.js 1.79 KiB [emitted] [immutable] [minimized] (name: main) asset images/logo.31b9235056a3dc35c4c5.png 6.4 KiB [emitted] [immutable] [from: images/logo.png] (auxiliary name: main) asset index.html 364 bytes [emitted] asset main.b231cc1c6e07b9d4ff06.css 122 bytes [emitted] [immutable] (name: main) ``` -------------------------------- ### Example Webpack 4 build output Source: https://relative-ci.com/documentation/guides/webpack-config Sample output showing assets generated with content hashes in Webpack 4. ```text Asset Size Chunks Chunk Names images/logo.31b9235056a3dc35c4c5d9806ab46e4f.png 6.4 KiB [emitted] [immutable] index.html 336 bytes [emitted] main.63b96e941d400fc1b806.css 122 bytes 0 [emitted] [immutable] main main.d7df904f48c9631839e8.js 1.75 KiB 0 [emitted] [immutable] main vendors.0e025fde233b62c30823.js 8.72 KiB 1 [emitted] [immutable] vendors ``` -------------------------------- ### Identify virtual modules Source: https://relative-ci.com/documentation/guides/bundle-stats/webpack-cli-webpack-stats Example of a virtual module path generated by plugins like vanilla-extract. ```text ./node_modules/@vanilla-extract/webpack-plugin/vanilla.virtual.css?%7B%22fileName%22%3A%22src%2Fcomponents%2Fcomponent%2Fcomponent.css.ts.vanilla.css%22%2C%22source%22%3A%22MODULE_CONTENT%22%7 ``` -------------------------------- ### Install @relative-ci/rollup-plugin Source: https://relative-ci.com/documentation/setup/agent/rollup-plugin Install the plugin as a development dependency using npm, yarn, or pnpm. ```bash npm install --save-dev @relative-ci/rollup-plugin ``` ```bash yarn add --dev @relative-ci/rollup-plugin ``` ```bash pnpm add -D @relative-ci/rollup-plugin ``` -------------------------------- ### Install @relative-ci/webpack-plugin v5 Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin/migrate-from-v4 Commands to uninstall the legacy v4 agent and install the new v5 webpack plugin using various package managers. ```bash # Uninstall @relative-ci/agent@v4 npm uninstall --save-dev @relative-ci/agent # Install @relative-ci/webpack-plugin@v5 npm install --save-dev @relative-ci/webpack-plugin ``` ```bash # Uninstall @relative-ci/agent@v4 yarn remove @relative-ci/agent # Install @relative-ci/webpack-plugin@v5 yarn add --dev @relative-ci/webpack-plugin ``` ```bash # Uninstall @relative-ci/agent@v4 pnpm remove --save-dev @relative-ci/agent # Install @relative-ci/webpack-plugin@v5 pnpm add --dev @relative-ci/webpack-plugin ``` -------------------------------- ### Uninstall v4 and Install v5 CLI Source: https://relative-ci.com/documentation/setup/agent/cli/migrate-from-v4 Commands to remove the legacy agent and install the new CLI using npm, yarn, or pnpm. ```bash # Uninstall @relative-ci/agent@v4 npm uninstall --save-dev @relative-ci/agent # Install @relative-ci/cli@v5 npm install --save-dev @relative-ci/cli ``` ```bash # Uninstall @relative-ci/agent@v4 yarn remove @relative-ci/agent # Install @relative-ci/cli@v5 yarn add --dev @relative-ci/cli ``` ```bash # Uninstall @relative-ci/agent@v4 pnpm remove --save-dev @relative-ci/agent # Install @relative-ci/cli@v5 pnpm add --save-dev @relative-ci/cli ``` -------------------------------- ### Configure RelativeCI in Dockerfile Source: https://relative-ci.com/documentation/setup/agent/build-information Example Dockerfile configuration for passing RelativeCI environment variables as build arguments. ```dockerfile from node:latest ## RelativeCI agent environment variables ARG CI=true ARG RELATIVE_CI_SERVICE="CI-SERVICE-container" ARG RELATIVE_CI_SLUG ARG RELATIVE_CI_KEY ARG RELATIVE_CI_BRANCH ARG RELATIVE_CI_PR ARG RELATIVE_CI_BASE_BRANCH ARG RELATIVE_CI_BUILD ARG RELATIVE_CI_BUILD_URL ARG RELATIVE_CI_COMMIT ARG RELATIVE_CI_COMMIT_MESSAGE ARG DEBUG COPY . /app WORKDIR /app RUN npm install RUN npm run build ``` -------------------------------- ### Configure Monorepo CI Pipeline Source: https://relative-ci.com/documentation/setup/agent/cli Example GitHub Actions workflow for running the CLI agent in a monorepo environment with separate API keys. ```yaml # ... - name: Project A - build run: cd project-a && npm run build --json webpack-stats.json - name: Project A - send build information and bundle stats to RelativeCI run: cd project-a && npx relative-ci env: RELATIVE_CI_KEY: ${{ secrets.RELATIVE_CI_KEY_PROJECT_A }} - name: Project B - build run: cd project-b && npm run build --json webpack-stats.json - name: Project B - send build information and bundle stats to RelativeCI run: cd project-b && npx relative-ci env: RELATIVE_CI_KEY: ${{ secrets.RELATIVE_CI_KEY_PROJECT_B }} ``` -------------------------------- ### Explain npm dependency resolution Source: https://relative-ci.com/documentation/guides/identify-and-fix-bundle-npm-duplicate-dependencies Use this command to inspect the dependency tree and identify why multiple versions of a package are installed. ```bash npm explain @ant-design/icons @ant-design/icons@4.6.0 node_modules/@ant-design/icons @ant-design/icons@"^4.6.0" from the root project @ant-design/icons@4.8.1 node_modules/antd/node_modules/@ant-design/icons @ant-design/icons@"^4.7.0" from antd@4.24.14 node_modules/antd antd@"^4.18.6" from the root projects ``` -------------------------------- ### Configure Vite 5/Rollup 4 Asset Filenames Source: https://relative-ci.com/documentation/guides/vite-config Example configuration for vite.config.js to ensure asset filenames follow patterns compatible with RelativeCI bundle analysis. ```javascript import { defineConfig } from 'vite'; import { webpackStats } from 'rollup-plugin-webpack-stats'; export default defineConfig((env) => ({ build: { rollupOptions: { output: { assetFileNames: 'assets/[name].[hash][extname]', chunkFileNames: 'assets/[name].[hash].js', entryFileNames: 'assets/[name].[hash].js', }, }, }, plugins: [webpackStats()], })); ``` -------------------------------- ### Configure GitHub Action for Monorepo Source: https://relative-ci.com/documentation/setup/agent/rollup-plugin Example of setting distinct API keys for different projects within a GitHub Actions workflow. ```yaml # ... - name: Project A - build run: cd project-a && npm build env: RELATIVE_CI_KEY: ${{ secrets.RELATIVE_CI_KEY_PROJECT_A }} - name: Project B - build run: cd project-b && npm build env: RELATIVE_CI_KEY: ${{ secrets.RELATIVE_CI_KEY_PROJECT_B }} ``` -------------------------------- ### Update dependency to a common version Source: https://relative-ci.com/documentation/guides/identify-and-fix-bundle-npm-duplicate-dependencies Install a specific version of a package to align with other dependencies and resolve conflicts. ```bash npm install --save @ant-design/icons@^4.8.1 example-fix-npm-dependencies@1.0.0 repo ├── @ant-design/icons@4.8.1 └─┬ antd@4.24.14 └── @ant-design/icons@4.8.1 deduped ``` -------------------------------- ### Pull Request Event Environment Variables Source: https://relative-ci.com/documentation/setup/agent/cli/github-action Example of environment variables set during a pull request event. ```bash GITHUB_REF='refs/pull/123/merge' GITHUB_SHA='Merge #abcd124 into #abcd123' ``` -------------------------------- ### Basic GitHub Action Workflow Configuration Source: https://relative-ci.com/documentation/setup/agent/cli/github-action Standard workflow configuration to run the RelativeCI agent after the build step. ```yaml name: Build on: push: jobs: build: steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup nodejs uses: actions/setup-node@v4 - name: Install dependencies run: npm ci - name: Build application and export webpack stats run: npm run build --json webpack-stats.json - name: Send webpack stats and build information to RelativeCI run: npx relative-ci env: RELATIVE_CI_KEY: ${{ secrets.RELATIVE_CI_KEY }} ``` -------------------------------- ### Inspect dependency tree with npm list Source: https://relative-ci.com/documentation/guides/identify-and-fix-bundle-npm-duplicate-dependencies Use the npm list command to visualize how different packages resolve to multiple versions of the same dependency. ```bash npm list @ant-design/icons example-fix-npm-dependencies@1.0.0 repo ├── @ant-design/icons@4.7.0 └─┬ antd@4.24.14 └── @ant-design/icons@4.8.1 ``` -------------------------------- ### Generate webpack stats in Create React App Source: https://relative-ci.com/documentation/guides/bundle-stats/create-react-app-webpack-stats Run this command to build the project and output a bundle-stats.json file in the build directory. ```bash npx react-scripts build --stats ``` -------------------------------- ### Asynchronous Component Imports Source: https://relative-ci.com/documentation/guides/vite-config Example of React.lazy imports that result in multiple chunks named 'index' when using default Rollup configuration. ```javascript const RepoDetailsAsync = React.lazy(async () => { // import components/repo-details/index.js const chunk = await import('./components/repo-details'); return { default: chunk.RepoDetails }; }); const RepoListAsync = React.lazy(async () => { // import components/repo-list/index.js const chunk = await import('./components/repo-list'); return { default: chunk.RepoList }; }); const AboutAsync = React.lazy(async () => { // import components/about/index.js const chunk = await import('./components/about'); return { default: chunk.About }; }); ``` -------------------------------- ### Configure GitHub Action for push event Source: https://relative-ci.com/documentation/setup/agent/github-action Add the relative-ci/agent-action step after the build process to send bundle statistics to RelativeCI. ```yaml name: Build on: push: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 'latest' # Install dependencies - run: npm ci # Build and output bundle stats to webpack-stats.json - run: npm run build -- --json webpack-stats.json # Send bundle stats and build information to RelativeCI - name: Send bundle stats to RelativeCI uses: relative-ci/agent-action@v3 with: webpackStatsFile: ./webpack-stats.json key: ${{ secrets.RELATIVE_CI_KEY }} ``` -------------------------------- ### Configure config-overrides.js Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Create a config-overrides.js file to register the RelativeCIAgentPlugin. ```javascript const { override, addWebpackPlugin } = require('customize-cra'); const RelativeCIAgentPlugin = require('@relative-ci/webpack-plugin'); module.exports = override(addWebpackPlugin(new RelativeCIAgentPlugin())); ``` -------------------------------- ### Generate bundle stats file Source: https://relative-ci.com/documentation/guides/bundle-stats/vite Run the Vite build process to generate the webpack-stats.json file. ```bash npx vite build ✓ 1908 modules transformed. dist/index.html 0.30 kB dist/webpack-stats.json 55.13 kB dist/assets/utils-daa1a1f7.css 0.03 kB │ gzip: 0.05 kB dist/assets/about-86a446cc.js 79.09 kB │ gzip: 27.53 kB dist/assets/index-bcbba0ad.js 419.66 kB │ gzip: 137.03 kB ``` -------------------------------- ### Query initial JS size over time Source: https://relative-ci.com/documentation/setup/configure/integrations/metrics-forwarding-influxdb Aggregates initial JS size metrics over time windows using dashboard variables. ```flux from(bucket: "relative-ci-data") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) // Filter by measurement |> filter(fn: (r) => r["_measurement"] == "relative-ci") // Filter by metric name |> filter(fn: (r) => r["_field"] == "initialSizeJS") // Filter by RelativeCI project name dashboard variable |> filter(fn: (r) => r["name"] == v.relativeCIProjectName) // Filter by RelativeCI job branch dashboard variable |> filter(fn: (r) => r["branch"] == v.relativeCIJobBranch) // Get the latest value for every period |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false) ``` -------------------------------- ### Build Output with Unique Chunk Names Source: https://relative-ci.com/documentation/guides/vite-config The resulting build output after applying the custom chunk naming logic. ```bash npm run build $ vite build vite v5.0.0 building for production... dist/index.html 0.31 kB │ gzip: 0.22 kB dist/assets/repo.8L8ZNlhE.css 0.03 kB │ gzip: 0.05 kB dist/assets/index._deYuKRK.css 546.34 kB │ gzip: 66.79 kB dist/assets/component-repo-list.ugpgMnKd.js 0.56 kB │ gzip: 0.38 kB dist/assets/CloseOutlined.0fpL38AF.js 0.66 kB │ gzip: 0.47 kB dist/assets/col.1yOZU9sX.js 4.48 kB │ gzip: 1.84 kB dist/assets/component-repo.SIhLG6w7.js 40.12 kB │ gzip: 13.12 kB dist/assets/component-about._xXEM7JY.js 79.56 kB │ gzip: 26.66 kB dist/assets/component-repo-details.BUE-6VoT.js 117.50 kB │ gzip: 36.85 kB dist/assets/index.UC00wnqI.js 414.35 kB │ gzip: 136.96 kB ✓ built in 3.00s ``` -------------------------------- ### Configure Travis CI for RelativeCI Source: https://relative-ci.com/documentation/setup/agent/cli/travis-ci Add these commands to your .travis.yml file to generate webpack stats and run the RelativeCI analysis after the build. ```yaml script: - npm run build --json webpack-stats.json - npx relative-ci ``` -------------------------------- ### Generate webpack stats file Source: https://relative-ci.com/documentation/guides/bundle-stats/webpack-stats-plugin Run the webpack build process to output the stats JSON file. ```bash npx webpack --mode production asset ../webpack-stats.json [emitted] ``` -------------------------------- ### Default Build Output Source: https://relative-ci.com/documentation/guides/vite-config The build output showing multiple chunks named 'index' which causes issues for bundle analysis tools. ```bash npm run build $ vite build vite v5.0.0 building for production... dist/index.html 0.31 kB │ gzip: 0.22 kB dist/assets/index.8L8ZNlhE.css 0.03 kB │ gzip: 0.05 kB dist/assets/index._deYuKRK.css 546.34 kB │ gzip: 66.79 kB dist/assets/index.6DnQ4OBO.js 0.55 kB │ gzip: 0.37 kB dist/assets/CloseOutlined.OIXdgtwq.js 0.66 kB │ gzip: 0.47 kB dist/assets/col.3PcwYSue.js 4.48 kB │ gzip: 1.85 kB dist/assets/index.PzG5MeZ4.js 40.12 kB │ gzip: 13.12 kB dist/assets/index.gn3unjAa.js 79.56 kB │ gzip: 26.66 kB dist/assets/index.gEtOlbAq.js 117.49 kB │ gzip: 36.84 kB dist/assets/index.NooaB8q3.js 414.26 kB │ gzip: 136.94 kB ✓ built in 2.90s ``` -------------------------------- ### Build and Upload Bundle Stats Workflow Source: https://relative-ci.com/documentation/setup/agent/github-action Configures a build workflow to generate webpack stats and upload them as an artifact using the relative-ci/agent-upload-artifact-action. ```yaml name: Build on: push: branches: - master pull_request: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 'latest' # Install dependencies - run: npm ci # Build and output bundle stats - run: npm run build -- --json webpack-stats.json # Upload bundle stats artifact to use on relative-ci.yaml workflow - name: Upload webpack stats artifact uses: relative-ci/agent-upload-artifact-action@v2 with: webpackStatsFile: ./webpack-stats.json ``` -------------------------------- ### Configure @relative-ci/cli Source: https://relative-ci.com/documentation/setup/agent/cli Define the agent configuration using a dedicated config file. Ensure the webpack stats path matches your build output. ```javascript /** * @type {import('@relative-ci/cli').Config} */ export default { // Read commit message from the git logs, GitHub Action event data or GitHub API includeCommitMessage: true, // Save agent payload to disk for debugging // @example './relative-ci-payload.json', payloadFilepath: undefined, // Enable ingest payload compression compress: false, webpack: { // Path to Webpack stats JSON file stats: './webpack-stats.json', }, }; ``` ```typescript import { type Config } from '@relative-ci/cli'; export default { // Read commit message from the git logs, GitHub Action event data or GitHub API includeCommitMessage: true, // Save agent payload to disk for debugging // @example './relative-ci-payload.json', payloadFilepath: undefined, // Enable ingest payload compression compress: false, webpack: { // Path to Webpack stats JSON file stats: './webpack-stats.json' } } satisfies Config; ``` ```javascript /** * @type {import('@relative-ci/cli').Config} */ module.exports = { // Read commit message from the git logs, GitHub Action event data or GitHub API includeCommitMessage: true, // Save agent payload to disk for debugging // @example './relative-ci-payload.json', payloadFilepath: undefined, // Enable ingest payload compression compress: false, webpack: { // Path to Webpack stats JSON file stats: './webpack-stats.json', }, }; ``` -------------------------------- ### Enable debug logging Source: https://relative-ci.com/documentation/setup/agent/rollup-plugin/debug Set the DEBUG environment variable to view agent activity during the build process. ```bash DEBUG=relative-ci:agent npm run build ``` -------------------------------- ### Run CLI from a specific directory Source: https://relative-ci.com/documentation/setup/agent/cli/circle-ci Use the --config-dir argument to execute the CLI from a directory other than the project root. ```bash npx relative-ci --config-dir packages/components ``` -------------------------------- ### Supported Asset Filename Hash Patterns Source: https://relative-ci.com/documentation/guides/vite-config List of supported filename patterns for hex and base64url hashes used by bundle-stats for asset normalization. ```text # hex hash **/*.HASH.EXT **/*-HASH.EXT **/*_HASH.EXT **/*~HASH.EXT # base64url hash **/*.HASH.EXT **/*~HASH.EXT ``` -------------------------------- ### Compare and analyze webpack stats Source: https://relative-ci.com/documentation/guides/analyze-and-compare-webpack-bundle-changes-locally Run the bundle-stats command to compare the two generated JSON files and produce a report. ```bash npx bundle-stats feature-branch.json main.json ✔ Read Webpack stats files ↓ Read baseline data [skipped] → Missing baseline stats, see "--baseline" option. ↓ Write baseline data [skipped] → Not a baseline job (see --baseline). ✔ Process data ✔ Generate reports ✔ Save reports Artifacts: - dist/bundle-stats.html ``` -------------------------------- ### Configure Vite Source: https://relative-ci.com/documentation/setup/agent/rollup-plugin Add the plugin to the plugins array in your Vite configuration file. ```javascript import relativeCiAgent from '@relative-ci/rollup-plugin'; export default { // .. your config plugins: [ // ... your plugins relativeCiAgent(), ], }; ``` ```typescript import relativeCiAgent from '@relative-ci/rollup-plugin'; export default { // .. your config plugins: [ // ... your plugins relativeCiAgent(), ], }; ``` -------------------------------- ### Configure Vite for bundle stats Source: https://relative-ci.com/documentation/guides/bundle-stats/vite Add the plugin to vite.config.js and configure rollupOptions for consistent file naming. ```javascript import { defineConfig } from 'vite'; import webpackStatsPlugin from 'rollup-plugin-webpack-stats'; export default defineConfig((env) => ({ build: { rollupOptions: { output: { // Use a supported file pattern for Vite 5/Rollup 4 // @doc https://relative-ci.com/documentation/guides/vite-config assetFileNames: 'assets/[name].[hash][extname]', chunkFileNames: 'assets/[name].[hash].js', entryFileNames: 'assets/[name].[hash].js', }, }, }, plugins: [ // Output webpack-stats.json file webpackStatsPlugin(), ], })); ``` -------------------------------- ### Generate baseline webpack stats Source: https://relative-ci.com/documentation/guides/analyze-and-compare-webpack-bundle-changes-locally Switch to your default branch and generate the baseline stats file. ```bash # Switch to default branch git checkout main # Generate webpack stats npx webpack --mode production --json main.json ``` -------------------------------- ### Query bundle size with custom unit formatting Source: https://relative-ci.com/documentation/setup/configure/integrations/metrics-forwarding-influxdb Transforms the bundle size value into MiB using a custom bytesToMiB function. ```flux bytesToMiB = (tables=<-) => tables |> map(fn:(r) => ({ r with _value: string( v: float(v: (r._value * 100 / 1048576)) / 100.0 ) + "MiB" })) from(bucket: "relative-ci-data") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) // Filter by measurement |> filter(fn: (r) => r["_measurement"] == "relative-ci") // Filter by metric name |> filter(fn: (r) => r["_field"] == "bundleSize") // Filter by RelativeCI project name |> filter(fn: (r) => r["name"] == "web-app") // Filter by RelativeCI job branch |> filter(fn: (r) => r["branch"] == "master") // Select the last value |> last() // Format output value |> bytesToMiB() ``` -------------------------------- ### Define dashboard variables for project and branch Source: https://relative-ci.com/documentation/setup/configure/integrations/metrics-forwarding-influxdb Queries to populate dashboard dropdowns for project names and job branches. ```flux import "influxdata/influxdb/schema" schema.tagValues(bucket: "relative-ci-data", tag: "name") ``` ```flux import "influxdata/influxdb/schema" schema.tagValues(bucket: "relative-ci-data", tag: "branch") ``` -------------------------------- ### Configure Webpack plugin Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Add the RelativeCIAgentPlugin to your webpack configuration file. ```javascript import RelativeCIAgentPlugin from '@relative-ci/webpack-plugin'; export default { // ... your webpack config plugins: [ // ... other plugins new RelativeCIAgentPlugin(), ], }; ``` ```typescript import RelativeCIAgentPlugin from '@relative-ci/webpack-plugin'; export default { // ... your webpack config plugins: [ // ... other plugins new RelativeCIAgentPlugin(), ], }; ``` ```javascript const RelativeCIAgentPlugin = require('@relative-ci/webpack-plugin'); module.exports = { // ... your webpack config plugins: [ // ... other plugins new RelativeCIAgentPlugin(), ], }; ``` -------------------------------- ### Enable debug logging for @relative-ci/cli Source: https://relative-ci.com/documentation/setup/agent/cli/debug Set the DEBUG environment variable to view detailed agent configuration and payload information during execution. ```bash DEBUG=relative-ci:agent npx relative-ci ``` -------------------------------- ### Update Circle CI configuration Source: https://relative-ci.com/documentation/setup/agent/cli/circle-ci Add the build step and the relative-ci command to your .circleci/config.yml file. ```yaml version: 2 jobs: build: steps: - run: name: Build application & webpack stats command: npm run build --json webpack-stats.json - run: name: Send bundle stats and build information to Relative CI command: npx relative-ci ``` -------------------------------- ### Configure Webpack 5 production output Source: https://relative-ci.com/documentation/guides/webpack-config Production configuration for Webpack 5 using content hashes for entry, chunk, and asset files. ```javascript module.exports = { output: { // Configure entry file names filename: '[name].[contenthash].js', // Configure chunk file names chunkFilename: '[name].[chunkhash].js', // Configure asset file names assetModuleFilename: '[path][name].[contenthash][ext][query]', }, plugins: [ // CSS file name pattern when using mini-css-extract-plugin new MiniCssExtractPlugin({ filename: '[name].[contenthash].css', }), ], }; ``` -------------------------------- ### Configure npm Workspaces for RelativeCI Source: https://relative-ci.com/documentation/setup/agent/rollup-plugin Pass environment variables to npm workspaces and update package scripts to use project-specific keys. ```yaml # ... - run: npm run build --workspaces env: APP_1_RELATIVE_CI_KEY: ${{ secrets.APP_1_RELATIVE_CI_KEY }} APP_2_RELATIVE_CI_KEY: ${{ secrets.APP_2_RELATIVE_CI_KEY }} ``` ```json { "name": "app-1", "scripts": { "build": "RELATIVE_CI_KEY=$APP_1_RELATIVE_CI_KEY npm run build" } } ``` ```json { "name": "app-2", "scripts": { "build": "RELATIVE_CI_KEY=$APP_2_RELATIVE_CI_KEY npm run build" } } ``` -------------------------------- ### Generate webpack stats JSON file Source: https://relative-ci.com/documentation/guides/bundle-stats/webpack-cli-webpack-stats Command to execute webpack and output the stats to a JSON file. ```bash npx webpack --mode production --json webpack-stats.json [webpack-cli] stats are successfully stored as json to webpack-stats.json ``` -------------------------------- ### Configure Lerna for RelativeCI Source: https://relative-ci.com/documentation/setup/agent/rollup-plugin Pass environment variables to Lerna build tasks and update project-specific package scripts. ```yaml # ... - run: npx lerna run build env: APP_1_RELATIVE_CI_KEY: ${{ secrets.APP_1_RELATIVE_CI_KEY }} APP_2_RELATIVE_CI_KEY: ${{ secrets.APP_2_RELATIVE_CI_KEY }} ``` ```json { "name": "app-1", "scripts": { "build": "RELATIVE_CI_KEY=$APP_1_RELATIVE_CI_KEY npm run build" } } ``` ```json { "name": "app-2", "scripts": { "build": "RELATIVE_CI_KEY=$APP_2_RELATIVE_CI_KEY npm run build" } } ``` -------------------------------- ### Configure Rspack plugin Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Add the RelativeCIAgentPlugin to your Rspack configuration file. ```javascript import RelativeCIAgentPlugin from '@relative-ci/webpack-plugin'; export default { // ... your rspack config plugins: [ // ... other plugins new RelativeCIAgentPlugin(), ], }; ``` ```typescript import RelativeCIAgentPlugin from '@relative-ci/webpack-plugin'; export default { // ... your rspack config plugins: [ // ... other plugins new RelativeCIAgentPlugin(), ], }; ``` ```javascript const RelativeCIAgentPlugin = require('@relative-ci/webpack-plugin'); module.exports = { // ... your rspack config plugins: [ // ... other plugins new RelativeCIAgentPlugin(), ], }; ``` -------------------------------- ### Configure Next.js plugin Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Integrate the plugin within the Next.js webpack configuration, ensuring it only runs during production builds. ```javascript import RelativeCIAgentPlugin from '@relative-ci/webpack-plugin'; const nextConfig = { // ... your next.js config webpack: function (config, options) { const { dev, isServer } = options; if (!dev && !isServer) { config.plugins.push(new RelativeCIAgentPlugin()); } // ... your custom Next.js webpack config return config; }, }; export default nextConfig; ``` ```typescript import RelativeCIAgentPlugin from '@relative-ci/webpack-plugin'; const nextConfig = { // ... your next.js config webpack: function (config, options) { const { dev, isServer } = options; if (!dev && !isServer) { config.plugins.push(new RelativeCIAgentPlugin()); } // ... your custom Next.js webpack config return config; }, }; export default nextConfig; ``` ```javascript const RelativeCIAgentPlugin = require('@relative-ci/webpack-plugin'); module.exports = { webpack: function (config, options) { const { dev, isServer } = options; if (!dev && !isServer) { config.plugins.push(new RelativeCIAgentPlugin()); } return config; }, }; ``` -------------------------------- ### Workflow Configuration with GitHub API Source: https://relative-ci.com/documentation/setup/agent/cli/github-action Passes the GITHUB_TOKEN to the agent to fetch commit details via the GitHub API. ```yaml name: Build on: push: branches: - master pull_request: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 'latest' # Install dependencies - run: npm ci # Build and output bundle stats to webpack-stats.json - run: npm run build -- --json webpack-stats.json # Send bundle stats and build information to RelativeCI - name: Send webpack stats and build information to RelativeCI run: npx relative-ci env: RELATIVE_CI_KEY: ${{ secrets.RELATIVE_CI_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ``` -------------------------------- ### Deduplicate npm dependencies Source: https://relative-ci.com/documentation/guides/identify-and-fix-bundle-npm-duplicate-dependencies Run this command to flatten the dependency tree and update the package-lock.json file. ```bash npm dedupe npm list @ant-design/icons example-fix-npm-dependencies@1.0.0 repo ├── @ant-design/icons@4.8.1 └─┬ antd@4.24.14 └── @ant-design/icons@4.8.1 deduped ``` -------------------------------- ### Configure Gatsby plugin Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Use the onCreateWebpackConfig hook to register the plugin during the build-javascript stage. ```javascript const RelativeCIAgentPlugin = require('@relative-ci/webpack-plugin'); exports.onCreateWebpackConfig = ({ stage, actions }) => { if (stage === 'build-javascript') { actions.setWebpackConfig({ plugins: [new RelativeCIAgentPlugin()], }); } }; ``` -------------------------------- ### Configure basic webpack stats Source: https://relative-ci.com/documentation/guides/bundle-stats/webpack-cli-webpack-stats Required stats options for the RelativeCI agent to extract data from assets, chunks, and modules. ```javascript module.exports = { // ... project webpack config stats: { assets: true, chunks: true, modules: true, }, }; ``` -------------------------------- ### Configure npm overrides Source: https://relative-ci.com/documentation/guides/identify-and-fix-bundle-npm-duplicate-dependencies Use the overrides field in package.json to force a specific version for a transitive dependency. ```json { "name": "app", /* ... */ "dependencies": { "@ant-design/icons": "^4.6.0", "antd": "^4.18.6" /* ... */ }, "overrides": { "antd": { "@ant-design/icons": "4.7.0" } } } ``` -------------------------------- ### RelativeCI Reporting Workflow Source: https://relative-ci.com/documentation/setup/agent/github-action Triggers on the completion of the build workflow to securely send bundle stats and build information to RelativeCI. ```yaml name: RelativeCI on: workflow_run: workflows: ['Build'] types: - completed jobs: build: runs-on: ubuntu-latest steps: - name: Send bundle stats and build information to RelativeCI uses: relative-ci/agent-action@v3 with: key: ${{ secrets.RELATIVE_CI_KEY }} token: ${{ secrets.GITHUB_TOKEN }} ``` -------------------------------- ### Update package.json scripts Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin Replace default react-scripts with react-app-rewired in your package.json. ```json "scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test" } ``` -------------------------------- ### Query bundle size using dashboard variables Source: https://relative-ci.com/documentation/setup/configure/integrations/metrics-forwarding-influxdb Uses dynamic dashboard variables to filter bundle size metrics by project and branch. ```flux bytesToMiB = (tables=<-) => tables |> map(fn:(r) => ({ r with _value: string( v: float(v: (r._value * 100 / 1048576)) / 100.0 ) + "MiB" })) from(bucket: "relative-ci-data") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) // Filter by measurement |> filter(fn: (r) => r["_measurement"] == "relative-ci") // Filter by metric name |> filter(fn: (r) => r["_field"] == "bundleSize") // Filter by RelativeCI project name dashboard variable |> filter(fn: (r) => r["name"] == v.relativeCIProjectName) // Filter by RelativeCI job branch dashboard variable |> filter(fn: (r) => r["branch"] == v.relativeCIJobBranch) // Select the last value |> last() // Format output value |> bytesToMiB() ``` -------------------------------- ### Configure webpack-stats-plugin in Next.js Source: https://relative-ci.com/documentation/guides/bundle-stats/nextjs-webpack-stats Add the StatsWriterPlugin to your next.config.js to output a webpack-stats.json file during production builds. ```javascript const { StatsWriterPlugin } = require('webpack-stats-plugin'); module.exports = { webpack: (config, options) => { const { dev, isServer } = options; // Output webpack stats JSON file only for // client-side/production build if (!dev && !isServer) { config.plugins.push( new StatsWriterPlugin({ filename: '../webpack-stats.json', stats: { assets: true, chunks: true, modules: true, }, }) ); } return config; }, }; ``` -------------------------------- ### Default Webpack stats configuration Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin The default webpack stats options used by the plugin. ```javascript { stats: { assets: true, chunks: true, modules: true, } } ``` -------------------------------- ### Configure Webpack 4 production output Source: https://relative-ci.com/documentation/guides/webpack-config Production configuration for Webpack 4 using file-loader and content hashes. ```javascript module.exports = { output: { // Configure entry file names filename: '[name].[contenthash].js', // Configure chunk file names chunkFilename: '[name].[chunkhash].js', }, module: { rules: [ // file name pattern when using file-loader { test: /\.(png|jpe?g|gif)$/i, loader: 'file-loader', options: { name: '[path][name].[contenthash].[ext]', }, }, ], }, plugins: [ // CSS file name pattern when using mini-css-extract-plugin new MiniCssExtractPlugin({ filename: '[name].[contenthash].css', }), ], }; ``` -------------------------------- ### Query bundle size single stat Source: https://relative-ci.com/documentation/setup/configure/integrations/metrics-forwarding-influxdb Retrieves the latest bundle size metric for a specific project and branch. ```flux from(bucket: "relative-ci-data") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) // Filter by measurement |> filter(fn: (r) => r["_measurement"] == "relative-ci") // Filter by metric name |> filter(fn: (r) => r["_field"] == "bundleSize") // Filter by RelativeCI project name |> filter(fn: (r) => r["name"] == "web-app") // Filter by RelativeCI job branch |> filter(fn: (r) => r["branch"] == "master") // Select the last value |> last() ``` -------------------------------- ### Configure RelativeCI for push and pull_request events in a monorepo Source: https://relative-ci.com/documentation/setup/agent/github-action Use this configuration to send bundle stats directly to RelativeCI for multiple projects within a single workflow file. ```yaml # ... # Project A - Send bundle stats and build information to RelativeCI - name: Project A - Send bundle stats to RelativeCI uses: relative-ci/agent-action@v3 with: webpackStatsFile: ./project-a/webpack-stats.json key: ${{ secrets.RELATIVE_CI_KEY_PROJECT_A }} token: ${{ secrets.GITHUB_TOKEN }} # Project B - Send bundle stats and build information to RelativeCI - name: Project B - Send bundle stats to RelativeCI uses: relative-ci/agent-action@v3 with: webpackStatsFile: ./project-b/webpack-stats.json key: ${{ secrets.RELATIVE_CI_KEY_PROJECT_B }} token: ${{ secrets.GITHUB_TOKEN }} ``` -------------------------------- ### Enable Webpack Plugin conditionally Source: https://relative-ci.com/documentation/setup/agent Configure the RelativeCiAgentWebpackPlugin to run only when a specific environment variable is set, preventing redundant execution during multiple build tasks. ```javascript const { RelativeCiAgentWebpackPlugin } = require('@relative-ci/agent'); module.exports = { // ... your webpack config plugins: [ // ... other plugins new RelativeCiAgentWebpackPlugin({ enabled: process.env.RELATIVE_CI }) ] }; ``` ```bash RELATIVE_CI=true npm run build ``` -------------------------------- ### Configure webpack-stats-plugin Source: https://relative-ci.com/documentation/guides/bundle-stats/webpack-stats-plugin Add the StatsWriterPlugin to your webpack configuration to generate the stats file. ```javascript const { StatsWriterPlugin } = require('webpack-stats-plugin'); module.exports = { // ... your webpack config plugins: [ // ... other plugins // Write stats file relative to the build directory new StatsWriterPlugin({ filename: '../webpack-stats.json', stats: { assets: true, chunks: true, modules: true, }, }), ], }; ``` -------------------------------- ### Update webpack configuration Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin/migrate-from-v4 Update the plugin import and instantiation in your webpack.config.js file to reflect the v5 package name. ```javascript - const { RelativeCiAgentWebpackPlugin } = require('@relative-ci/agent'); + const RelativeCIAgentPlugin = require('@relative-ci/webpack-plugin'); module.exports = { // ... your webpack config plugins: [ // ... other plugins - new RelativeCiAgentWebpackPlugin() + new RelativeCIAgentPlugin() ] }; ``` -------------------------------- ### Define supported content hash patterns Source: https://relative-ci.com/documentation/guides/webpack-config Patterns used by bundle-stats to normalize asset paths by removing hashes for comparison. ```text # hex hash **/*.HASH.EXT **/*-HASH.EXT **/*_HASH.EXT **/*~HASH.EXT # base64url hash **/*.HASH.EXT **/*~HASH.EXT ``` -------------------------------- ### Verify npm overrides Source: https://relative-ci.com/documentation/guides/identify-and-fix-bundle-npm-duplicate-dependencies Check the resolved dependency version after applying overrides. ```bash npm list @ant-design/icons example-fix-npm-dependencies@1.0.0 ├── @ant-design/icons@4.7.0 └─┬ antd@4.24.14 └── @ant-design/icons@4.7.0 deduped ``` -------------------------------- ### Configure payload inspection Source: https://relative-ci.com/documentation/setup/agent/rollup-plugin/debug Write the agent's payload to a file on disk by setting the payloadFilepath option in the rollup configuration. ```javascript import relativeCiAgent from '@relative-ci/rollup-plugin'; export default { // ... your rollup config plugins: [ // ... other plugins relativeCiAgent({ payloadFilepath: './artifacts/relative-ci-payload.json', }), ], }; ``` -------------------------------- ### Configure payload inspection in webpack.config.js Source: https://relative-ci.com/documentation/setup/agent/webpack-plugin/debug Use the payloadFilepath option to save the agent's payload to a local file for inspection. ```javascript const RelativeCiAgentPlugin = require('@relative-ci/webpack-plugin'); module.exports = { // ... your webpack config plugins: [ // ... other plugins new RelativeCiAgentPlugin({ payloadFilepath: './artifacts/relative-ci-payload.json', }), ], }; ```