Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,28 @@ jobs:
files: packages/**/*.junit.xml
token: ${{ secrets.CODECOV_TOKEN }}

job_browser_bundler_tests:
name: Browser Bundler Tests
needs: [job_get_metadata, job_build]
timeout-minutes: 5
runs-on: ubuntu-24.04
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v5
with:
ref: ${{ env.HEAD_COMMIT }}
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version-file: 'package.json'
- name: Restore caches
uses: ./.github/actions/restore-cache
with:
dependency_cache_key: ${{ needs.job_build.outputs.dependency_cache_key }}

- name: Run bundler tests
run: yarn test:bundler

job_browser_playwright_tests:
name:
Playwright ${{ matrix.bundle }}${{ matrix.project && matrix.project != 'chromium' && format(' {0}',
Expand Down Expand Up @@ -1160,6 +1182,7 @@ jobs:
job_node_unit_tests,
job_node_integration_tests,
job_cloudflare_integration_tests,
job_browser_bundler_tests,
job_browser_playwright_tests,
job_browser_loader_tests,
job_remix_integration_tests,
Expand Down
22 changes: 11 additions & 11 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ module.exports = [
// Browser SDK (ESM)
{
name: '@sentry/browser',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init'),
gzip: true,
limit: '25 KB',
},
{
name: '@sentry/browser - with treeshaking flags',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init'),
gzip: true,
limit: '24.1 KB',
Expand All @@ -35,28 +35,28 @@ module.exports = [
},
{
name: '@sentry/browser (incl. Tracing)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration'),
gzip: true,
limit: '41.3 KB',
},
{
name: '@sentry/browser (incl. Tracing, Profiling)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'browserProfilingIntegration'),
gzip: true,
limit: '48 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration'),
gzip: true,
limit: '80 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay) - with treeshaking flags',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration'),
gzip: true,
limit: '75 KB',
Expand All @@ -79,35 +79,35 @@ module.exports = [
},
{
name: '@sentry/browser (incl. Tracing, Replay with Canvas)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'replayCanvasIntegration'),
gzip: true,
limit: '85 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay, Feedback)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '97 KB',
},
{
name: '@sentry/browser (incl. Feedback)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'feedbackIntegration'),
gzip: true,
limit: '42 KB',
},
{
name: '@sentry/browser (incl. sendFeedback)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'sendFeedback'),
gzip: true,
limit: '30 KB',
},
{
name: '@sentry/browser (incl. FeedbackAsync)',
path: 'packages/browser/build/npm/esm/index.js',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'feedbackAsyncIntegration'),
gzip: true,
limit: '35 KB',
Expand Down
12 changes: 6 additions & 6 deletions dev-packages/browser-integration-tests/utils/generatePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ const IMPORTED_INTEGRATION_CDN_BUNDLE_PATHS: Record<string, string> = {

const BUNDLE_PATHS: Record<string, Record<string, string>> = {
browser: {
cjs: 'build/npm/cjs/index.js',
esm: 'build/npm/esm/index.js',
cjs: 'build/npm/cjs/prod/index.js',
esm: 'build/npm/esm/prod/index.js',
bundle: 'build/bundles/bundle.js',
bundle_min: 'build/bundles/bundle.min.js',
bundle_replay: 'build/bundles/bundle.replay.js',
Expand All @@ -67,8 +67,8 @@ const BUNDLE_PATHS: Record<string, Record<string, string>> = {
loader_tracing_replay: 'build/bundles/bundle.tracing.replay.debug.min.js',
},
integrations: {
cjs: 'build/npm/cjs/index.js',
esm: 'build/npm/esm/index.js',
cjs: 'build/npm/cjs/prod/index.js',
esm: 'build/npm/esm/prod/index.js',
bundle: 'build/bundles/[INTEGRATION_NAME].js',
bundle_min: 'build/bundles/[INTEGRATION_NAME].min.js',
},
Expand All @@ -77,8 +77,8 @@ const BUNDLE_PATHS: Record<string, Record<string, string>> = {
bundle_min: 'build/bundles/[INTEGRATION_NAME].min.js',
},
wasm: {
cjs: 'build/npm/cjs/index.js',
esm: 'build/npm/esm/index.js',
cjs: 'build/npm/cjs/prod/index.js',
esm: 'build/npm/esm/prod/index.js',
bundle: 'build/bundles/wasm.js',
bundle_min: 'build/bundles/wasm.min.js',
},
Expand Down
6 changes: 6 additions & 0 deletions dev-packages/bundler-tests/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['../../.eslintrc.js'],
parserOptions: {
sourceType: 'module',
},
};
6 changes: 6 additions & 0 deletions dev-packages/bundler-tests/fixtures/basic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!doctype html>
<html lang="en">
<body>
<script type="module" src="/index.js"></script>
</body>
</html>
5 changes: 5 additions & 0 deletions dev-packages/bundler-tests/fixtures/basic/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { init } from '@sentry/browser';

init({
dsn: 'https://[email protected]/0000000',
});
26 changes: 26 additions & 0 deletions dev-packages/bundler-tests/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@sentry-internal/bundler-tests",
"version": "10.22.0",
"description": "Bundler tests for Sentry Browser SDK",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/bundler-tests",
"author": "Sentry",
"license": "MIT",
"private": true,
"main": "./index.mjs",
"scripts": {
"test": "vitest run"
},
"dependencies": {
"@sentry/browser": "10.22.0",
"webpack": "^5.0.0",
"rollup": "^4.0.0",
"vite": "^7.0.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"vitest": "^3.2.4"
},
"volta": {
"extends": "../../package.json"
},
"type": "module"
}
144 changes: 144 additions & 0 deletions dev-packages/bundler-tests/tests/bundling.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { describe, expect, beforeAll, test } from 'vitest';
import * as path from 'node:path';
import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url';

import webpack from 'webpack';
import { rollup } from 'rollup';
import { build as viteBuild } from 'vite';
import nodeResolve from '@rollup/plugin-node-resolve';

// Helper functions
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

function distDir(name: string): string {
const dir = path.join(__dirname, '..', 'dist', name);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
return dir;
}

function rimraf(dir: string): void {
if (fs.existsSync(dir)) {
fs.rmSync(dir, { recursive: true, force: true });
}
}

function readAllJs(outDir: string): string {
let contents = '';
const stack = [outDir];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while (stack.length) {
const current = stack.pop()!;
for (const entry of fs.readdirSync(current)) {
const full = path.join(current, entry);
const stat = fs.statSync(full);
if (stat.isDirectory()) {
stack.push(full);
} else if (entry.endsWith('.js') || entry.endsWith('.mjs')) {
contents += fs.readFileSync(full, 'utf8');
}
}
}
return contents;
}

function fixtureEntry(name: string): string {
return path.resolve(__dirname, '..', 'fixtures', name, 'index.js');
}

function rootDir(): string {
return path.join(__dirname, '../../..');
}

const SPOTLIGHT_URL = 'localhost:8969';

type BundleMode = 'development' | 'production';

function bundleWithWebpack(mode: BundleMode): Promise<string> {
return new Promise((resolve, reject) => {
const outDir = distDir(`webpack-${mode}`);
rimraf(outDir);
const compiler = webpack({
mode,
entry: fixtureEntry('basic'),
output: { path: outDir, filename: 'bundle.js' },
});
compiler?.run((err: Error | null | undefined, stats: webpack.Stats | undefined) => {
try {
if (err) throw err;
if (stats?.hasErrors()) {
throw new Error(stats.toString('errors-only'));
}
resolve(readAllJs(outDir));
} catch (e) {
reject(e);
} finally {
compiler.close(() => {});
}
});
});
}

async function bundleWithRollup(mode: BundleMode): Promise<string> {
const outDir = distDir(`rollup-${mode}`);
rimraf(outDir);

const bundle = await rollup({
input: fixtureEntry('basic'),
plugins: [
nodeResolve({
// There should really be a default where these get specified automatically
exportConditions: [mode === 'production' ? 'production' : 'development'],
}),
],
});
await bundle.write({ dir: outDir, format: 'esm' });
await bundle.close();
return readAllJs(outDir);
}

async function bundleWithVite(mode: BundleMode): Promise<string> {
const outDir = distDir(`vite-${mode}`);
rimraf(outDir);

// In Vitest, NODE_ENV is always 'test', so we need to override it here
const prev = process.env.NODE_ENV;
process.env.NODE_ENV = mode;

await viteBuild({
mode,
root: path.dirname(fixtureEntry('basic')),
build: { outDir, minify: mode === 'production' },
});

process.env.NODE_ENV = prev;

return readAllJs(outDir);
}

describe('spotlight', () => {
beforeAll(() => {
const distRoot = path.join(rootDir(), 'dist');
rimraf(distRoot);
});

const cases: [string, (mode: BundleMode) => Promise<string>][] = [
['webpack', bundleWithWebpack],
['rollup', bundleWithRollup],
['vite', bundleWithVite],
];

for (const [name, bundler] of cases) {
test(`${name} development bundle contains spotlight`, async () => {
const code = await bundler('development');
expect(code).includes(SPOTLIGHT_URL);

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Unit Tests

tests/bundling.test.ts > spotlight > vite development bundle contains spotlight

AssertionError: expected '(function polyfill() {\n const relLi…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Unit Tests

tests/bundling.test.ts > spotlight > rollup development bundle contains spotlight

AssertionError: expected '/**\n * This serves as a build time f…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Unit Tests

tests/bundling.test.ts > spotlight > webpack development bundle contains spotlight

AssertionError: expected '/*\n * ATTENTION: The "eval" devtool …' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Browser Bundler Tests

tests/bundling.test.ts > spotlight > vite development bundle contains spotlight

AssertionError: expected '(function polyfill() {\n const relLi…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Browser Bundler Tests

tests/bundling.test.ts > spotlight > rollup development bundle contains spotlight

AssertionError: expected '/**\n * This serves as a build time f…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Browser Bundler Tests

tests/bundling.test.ts > spotlight > webpack development bundle contains spotlight

AssertionError: expected '/*\n * ATTENTION: The "eval" devtool …' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (22) Unit Tests

tests/bundling.test.ts > spotlight > vite development bundle contains spotlight

AssertionError: expected '(function polyfill() {\n const relLi…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (22) Unit Tests

tests/bundling.test.ts > spotlight > rollup development bundle contains spotlight

AssertionError: expected '/**\n * This serves as a build time f…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (22) Unit Tests

tests/bundling.test.ts > spotlight > webpack development bundle contains spotlight

AssertionError: expected '/*\n * ATTENTION: The "eval" devtool …' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (24) Unit Tests

tests/bundling.test.ts > spotlight > vite development bundle contains spotlight

AssertionError: expected '(function polyfill() {\n const relLi…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (24) Unit Tests

tests/bundling.test.ts > spotlight > rollup development bundle contains spotlight

AssertionError: expected '/**\n * This serves as a build time f…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (24) Unit Tests

tests/bundling.test.ts > spotlight > webpack development bundle contains spotlight

AssertionError: expected '/*\n * ATTENTION: The "eval" devtool …' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Unit Tests

tests/bundling.test.ts > spotlight > vite development bundle contains spotlight

AssertionError: expected '(function polyfill() {\n const relLi…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Unit Tests

tests/bundling.test.ts > spotlight > rollup development bundle contains spotlight

AssertionError: expected '/**\n * This serves as a build time f…' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20

Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Unit Tests

tests/bundling.test.ts > spotlight > webpack development bundle contains spotlight

AssertionError: expected '/*\n * ATTENTION: The "eval" devtool …' to include 'localhost:8969' ❯ tests/bundling.test.ts:136:20
});

test(`${name} production bundle does not contain spotlight`, async () => {

Check failure on line 139 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Unit Tests

tests/bundling.test.ts > spotlight > webpack production bundle does not contain spotlight

Error: Test timed out in 5000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ tests/bundling.test.ts:139:5

Check failure on line 139 in dev-packages/bundler-tests/tests/bundling.test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Unit Tests

tests/bundling.test.ts > spotlight > webpack production bundle does not contain spotlight

Error: Test timed out in 5000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ tests/bundling.test.ts:139:5
const code = await bundler('production');
expect(code).not.includes(SPOTLIGHT_URL);
});
}
});
9 changes: 9 additions & 0 deletions dev-packages/bundler-tests/vitest.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
include: ['tests/**/*.test.*s'],
timeout: 10000,
hookTimeout: 10000,
},
});
10 changes: 10 additions & 0 deletions dev-packages/bundler-tests/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const path = require('path');

module.exports = (env, argv) => ({
mode: argv.mode || 'development',
entry: path.resolve(__dirname, 'fixtures/basic/index.js'),
output: {
path: path.resolve(__dirname, 'dist/webpack-' + (argv.mode || 'development')),
filename: 'bundle.js',
},
});
Loading
Loading