Skip to content
Open
Show file tree
Hide file tree
Changes from all 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://00000000000000000000000000000000@o000000.ingest.sentry.io/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];
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);
});

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