Skip to content
Open
Show file tree
Hide file tree
Changes from 18 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
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.23.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.23.0",
"webpack": "^5.0.0",
"rollup": "^4.0.0",
"vite": "^5.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 / Browser 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 / Browser 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 / Browser 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 () => {
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',
},
});
7 changes: 3 additions & 4 deletions dev-packages/rollup-utils/bundleHelpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
makeCleanupPlugin,
makeCommonJSPlugin,
makeIsDebugBuildPlugin,
makeJsonPlugin,
makeLicensePlugin,
makeNodeResolvePlugin,
makeRrwebBuildPlugin,
Expand All @@ -20,6 +19,7 @@ import {
makeTerserPlugin,
} from './plugins/index.mjs';
import { mergePlugins } from './utils.mjs';
import { makeProductionReplacePlugin } from './plugins/npmPlugins.mjs';

const BUNDLE_VARIANTS = ['.js', '.min.js', '.debug.min.js'];

Expand All @@ -35,14 +35,13 @@ export function makeBaseBundleConfig(options) {
excludeIframe: false,
excludeShadowDom: false,
});
const productionReplacePlugin = makeProductionReplacePlugin();

// The `commonjs` plugin is the `esModuleInterop` of the bundling world. When used with `transformMixedEsModules`, it
// will include all dependencies, imported or required, in the final bundle. (Without it, CJS modules aren't included
// at all, and without `transformMixedEsModules`, they're only included if they're imported, not if they're required.)
const commonJSPlugin = makeCommonJSPlugin({ transformMixedEsModules: true });

const jsonPlugin = makeJsonPlugin();

// used by `@sentry/browser`
const standAloneBundleConfig = {
output: {
Expand Down Expand Up @@ -119,7 +118,7 @@ export function makeBaseBundleConfig(options) {
strict: false,
esModule: false,
},
plugins: [sucrasePlugin, nodeResolvePlugin, cleanupPlugin],
plugins: [productionReplacePlugin, sucrasePlugin, nodeResolvePlugin, cleanupPlugin],
treeshake: 'smallest',
};

Expand Down
Loading
Loading