-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(browser): Include Spotlight in development bundles #18078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 18 commits
4805008
aae7360
18d31e5
84ff77d
92bc9f6
1cb7253
eb515c4
e72bc89
83b3890
8fff1ab
2c86f37
0e52d5e
9fc0f3f
c48144c
7229c7a
eb3e548
5202eec
51c05d2
4ea4e31
5d2f9ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| module.exports = { | ||
| extends: ['../../.eslintrc.js'], | ||
| parserOptions: { | ||
| sourceType: 'module', | ||
| }, | ||
| }; |
| 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> |
| 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', | ||
| }); |
| 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" | ||
| } |
| 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); | ||
|
Check failure on line 136 in dev-packages/bundler-tests/tests/bundling.test.ts
|
||
timfish marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
|
|
||
| test(`${name} production bundle does not contain spotlight`, async () => { | ||
| const code = await bundler('production'); | ||
| expect(code).not.includes(SPOTLIGHT_URL); | ||
timfish marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
| } | ||
| }); | ||
| 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, | ||
| }, | ||
| }); |
| 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', | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a simpler and probably more efficient way now: https://github.com/getsentry/sentry-docs/pull/13994/files#diff-a17104741f091f6ca105b7bd4f8272c206b4575306615ebac8a847cc004591c3R45-R50