From 17e6cb2c649fefdab131ebf4e194b9e8d33c779e Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Tue, 27 Aug 2024 15:56:45 +0200 Subject: [PATCH 01/15] feat(solidstart): Add `sentrySolidStartVite` plugin --- packages/solidstart/.eslintrc.js | 1 + packages/solidstart/README.md | 54 ++++------- packages/solidstart/package.json | 13 ++- packages/solidstart/src/index.server.ts | 1 + packages/solidstart/src/index.types.ts | 1 + packages/solidstart/src/vite/index.ts | 1 + .../src/vite/sentrySolidStartVite.ts | 18 ++++ packages/solidstart/src/vite/sourceMaps.ts | 56 +++++++++++ packages/solidstart/src/vite/types.ts | 94 +++++++++++++++++++ .../withServerActionInstrumentation.test.ts | 2 +- .../test/vite/sentrySolidStartVite.test.ts | 53 +++++++++++ .../solidstart/test/vite/sourceMaps.test.ts | 58 ++++++++++++ 12 files changed, 312 insertions(+), 40 deletions(-) create mode 100644 packages/solidstart/src/vite/index.ts create mode 100644 packages/solidstart/src/vite/sentrySolidStartVite.ts create mode 100644 packages/solidstart/src/vite/sourceMaps.ts create mode 100644 packages/solidstart/src/vite/types.ts create mode 100644 packages/solidstart/test/vite/sentrySolidStartVite.test.ts create mode 100644 packages/solidstart/test/vite/sourceMaps.test.ts diff --git a/packages/solidstart/.eslintrc.js b/packages/solidstart/.eslintrc.js index c1f55c94aadf..d567b12530d0 100644 --- a/packages/solidstart/.eslintrc.js +++ b/packages/solidstart/.eslintrc.js @@ -14,6 +14,7 @@ module.exports = { files: ['src/vite/**', 'src/server/**'], rules: { '@sentry-internal/sdk/no-optional-chaining': 'off', + '@sentry-internal/sdk/no-nullish-coalescing': 'off', }, }, ], diff --git a/packages/solidstart/README.md b/packages/solidstart/README.md index 0b25a3a37e3e..cf6c393c407a 100644 --- a/packages/solidstart/README.md +++ b/packages/solidstart/README.md @@ -157,58 +157,36 @@ render( ); ``` -# Sourcemaps and Releases +## Uploading Source Maps -To generate and upload source maps of your Solid Start app use our Vite bundler plugin. - -1. Install the Sentry Vite plugin - -```bash -# Using npm -npm install @sentry/vite-plugin --save-dev - -# Using yarn -yarn add @sentry/vite-plugin --dev -``` - -2. Configure the vite plugin - -To upload source maps you have to configure an auth token. Auth tokens can be passed to the plugin explicitly with the -`authToken` option, with a `SENTRY_AUTH_TOKEN` environment variable, or with an `.env.sentry-build-plugin` file in the -working directory when building your project. We recommend you add the auth token to your CI/CD environment as an -environment variable. +To upload source maps, add the `sentrySolidStartVite` plugin from `@sentry/solidstart` to your `app.config.ts` and configure +an auth token. Auth tokens can be passed to the plugin explicitly with the `authToken` option, with a +`SENTRY_AUTH_TOKEN` environment variable, or with an `.env.sentry-build-plugin` file in the working directory when +building your project. We recommend you add the auth token to your CI/CD environment as an environment variable. Learn more about configuring the plugin in our [Sentry Vite Plugin documentation](https://www.npmjs.com/package/@sentry/vite-plugin). -```bash -// .env.sentry-build-plugin -SENTRY_AUTH_TOKEN= -SENTRY_ORG= -SENTRY_PROJECT= -``` - -3. Finally, add the plugin to your `app.config.ts` file. - -```javascript +```typescript +// app.config.ts import { defineConfig } from '@solidjs/start/config'; -import { sentryVitePlugin } from '@sentry/vite-plugin'; +import { sentrySolidStartVite } from '@sentry/solidstart'; export default defineConfig({ - // rest of your config // ... vite: { - build: { - sourcemap: true, - }, plugins: [ - sentryVitePlugin({ - org: process.env.SENTRY_ORG, - project: process.env.SENTRY_PROJECT, - authToken: process.env.SENTRY_AUTH_TOKEN, + sentrySolidStartVite({ + sourceMapsUploadOptions: { + org: process.env.SENTRY_ORG, + project: process.env.SENTRY_PROJECT, + authToken: process.env.SENTRY_AUTH_TOKEN, + }, + debug: true, }), ], }, + // ... }); ``` diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index 80de3c6b5b36..c829c8b6d1a5 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -39,6 +39,17 @@ "require": "./build/cjs/index.server.js" } }, + "./middleware": { + "types": "./middleware.d.ts", + "import": { + "types": "./middleware.d.ts", + "default": "./build/esm/middleware.js" + }, + "require": { + "types": "./middleware.d.ts", + "default": "./build/cjs/middleware.js" + } + }, "./solidrouter": { "types": "./solidrouter.d.ts", "browser": { @@ -95,7 +106,7 @@ "build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch", "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:tarball": "npm pack", - "circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts && madge --circular src/solidrouter.client.ts && madge --circular src/solidrouter.server.ts && madge --circular src/solidrouter.ts", + "circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts && madge --circular src/solidrouter.client.ts && madge --circular src/solidrouter.server.ts && madge --circular src/solidrouter.ts && madge --circular src/middleware.ts", "clean": "rimraf build coverage sentry-solidstart-*.tgz ./*.d.ts ./*.d.ts.map ./client ./server", "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", diff --git a/packages/solidstart/src/index.server.ts b/packages/solidstart/src/index.server.ts index 0ce5251aa327..d675a1c72820 100644 --- a/packages/solidstart/src/index.server.ts +++ b/packages/solidstart/src/index.server.ts @@ -1 +1,2 @@ export * from './server'; +export * from './vite'; diff --git a/packages/solidstart/src/index.types.ts b/packages/solidstart/src/index.types.ts index 89eaa14662e3..51adf848775a 100644 --- a/packages/solidstart/src/index.types.ts +++ b/packages/solidstart/src/index.types.ts @@ -3,6 +3,7 @@ // exports in this file - which we do below. export * from './client'; export * from './server'; +export * from './vite'; import type { Integration, Options, StackParser } from '@sentry/types'; diff --git a/packages/solidstart/src/vite/index.ts b/packages/solidstart/src/vite/index.ts new file mode 100644 index 000000000000..464bbd604fbe --- /dev/null +++ b/packages/solidstart/src/vite/index.ts @@ -0,0 +1 @@ +export * from './sentrySolidStartVite'; diff --git a/packages/solidstart/src/vite/sentrySolidStartVite.ts b/packages/solidstart/src/vite/sentrySolidStartVite.ts new file mode 100644 index 000000000000..28c1125a47b2 --- /dev/null +++ b/packages/solidstart/src/vite/sentrySolidStartVite.ts @@ -0,0 +1,18 @@ +import type { Plugin } from 'vite'; +import { makeSourceMapsVitePlugin } from './sourceMaps'; +import type { SentrySolidStartPluginOptions } from './types'; + +/** + * Various Sentry vite plugins to be used for SolidStart. + */ +export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions): Plugin[] => { + const sentryPlugins: Plugin[] = []; + + if (process.env.NODE_ENV !== 'development') { + if (options.sourceMapsUploadOptions?.enabled ?? true) { + sentryPlugins.push(...makeSourceMapsVitePlugin({ ...options.sourceMapsUploadOptions, debug: options.debug })); + } + } + + return sentryPlugins; +}; diff --git a/packages/solidstart/src/vite/sourceMaps.ts b/packages/solidstart/src/vite/sourceMaps.ts new file mode 100644 index 000000000000..2133edbfa9dd --- /dev/null +++ b/packages/solidstart/src/vite/sourceMaps.ts @@ -0,0 +1,56 @@ +import { sentryVitePlugin } from '@sentry/vite-plugin'; +import type { Plugin } from 'vite'; +import type { SourceMapsOptions } from './types'; + +/** + * A Sentry plugin for SolidStart to enable source maps and use + * @sentry/vite-plugin to automatically upload source maps to Sentry. + * @param {SourceMapsOptions} options + */ +export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { + return [ + { + name: 'sentry-solidstart-source-maps', + apply: 'build', + enforce: 'post', + config(config) { + const sourceMapsPreviouslyNotEnabled = !config.build?.sourcemap; + if (options.debug && sourceMapsPreviouslyNotEnabled) { + // eslint-disable-next-line no-console + console.log('[Sentry SolidStart Plugin] Enabling source map generation'); + if (!options.sourcemaps?.filesToDeleteAfterUpload) { + // eslint-disable-next-line no-console + console.warn( + `[Sentry SolidStart PLugin] We recommend setting the \`sourceMapsUploadOptions.sourcemaps.filesToDeleteAfterUpload\` option to clean up source maps after uploading. +[Sentry SolidStart Plugin] Otherwise, source maps might be deployed to production, depending on your configuration`, + ); + } + } + return { + ...config, + build: { + ...config.build, + sourcemap: true, + }, + }; + }, + }, + ...sentryVitePlugin({ + org: options.org ?? process.env.SENTRY_ORG, + project: options.project ?? process.env.SENTRY_PROJECT, + authToken: options.authToken ?? process.env.SENTRY_AUTH_TOKEN, + telemetry: options.telemetry ?? true, + sourcemaps: { + assets: options.sourcemaps?.assets ?? undefined, + ignore: options.sourcemaps?.ignore ?? undefined, + filesToDeleteAfterUpload: options.sourcemaps?.filesToDeleteAfterUpload ?? undefined, + }, + _metaOptions: { + telemetry: { + metaFramework: 'solidstart', + }, + }, + debug: options.debug ?? false, + }), + ]; +} diff --git a/packages/solidstart/src/vite/types.ts b/packages/solidstart/src/vite/types.ts new file mode 100644 index 000000000000..0a1c6dc81acb --- /dev/null +++ b/packages/solidstart/src/vite/types.ts @@ -0,0 +1,94 @@ +export type SourceMapsOptions = { + /** + * If this flag is `true`, and an auth token is detected, the Sentry SDK will + * automatically generate and upload source maps to Sentry during a production build. + * + * @default true + */ + enabled?: boolean; + + /** + * The auth token to use when uploading source maps to Sentry. + * + * Instead of specifying this option, you can also set the `SENTRY_AUTH_TOKEN` environment variable. + * + * To create an auth token, follow this guide: + * @see https://docs.sentry.io/product/accounts/auth-tokens/#organization-auth-tokens + */ + authToken?: string; + + /** + * The organization slug of your Sentry organization. + * Instead of specifying this option, you can also set the `SENTRY_ORG` environment variable. + */ + org?: string; + + /** + * The project slug of your Sentry project. + * Instead of specifying this option, you can also set the `SENTRY_PROJECT` environment variable. + */ + project?: string; + + /** + * If this flag is `true`, the Sentry plugin will collect some telemetry data and send it to Sentry. + * It will not collect any sensitive or user-specific data. + * + * @default true + */ + telemetry?: boolean; + + /** + * Options related to sourcemaps + */ + sourcemaps?: { + /** + * A glob or an array of globs that specify the build artifacts and source maps that will be uploaded to Sentry. + * + * The globbing patterns must follow the implementation of the `glob` package. + * @see https://www.npmjs.com/package/glob#glob-primer + */ + assets?: string | Array; + + /** + * A glob or an array of globs that specifies which build artifacts should not be uploaded to Sentry. + * + * @default [] - By default no files are ignored. Thus, all files matching the `assets` glob + * or the default value for `assets` are uploaded. + * + * The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob) + */ + ignore?: string | Array; + + /** + * A glob or an array of globs that specifies the build artifacts that should be deleted after the artifact + * upload to Sentry has been completed. + * + * @default [] - By default no files are deleted. + * + * The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob) + */ + filesToDeleteAfterUpload?: string | Array; + }; + + /** + * Enable debug functionality of the SDK during build-time. + * Enabling this will give you logs about source maps. + */ + debug?: boolean; +}; + +/** + * Build options for the Sentry module. These options are used during build-time by the Sentry SDK. + */ +export type SentrySolidStartPluginOptions = { + /** + * Options for the Sentry Vite plugin to customize the source maps upload process. + */ + sourceMapsUploadOptions?: SourceMapsOptions; + + /** + * Enable debug functionality of the SDK during build-time. + * Enabling this will give you, for example logs about source maps. + */ + debug?: boolean; +}; diff --git a/packages/solidstart/test/server/withServerActionInstrumentation.test.ts b/packages/solidstart/test/server/withServerActionInstrumentation.test.ts index 9a5b1e0c2b51..6bc70d30ae07 100644 --- a/packages/solidstart/test/server/withServerActionInstrumentation.test.ts +++ b/packages/solidstart/test/server/withServerActionInstrumentation.test.ts @@ -10,9 +10,9 @@ import { spanToJSON, } from '@sentry/node'; import { NodeClient } from '@sentry/node'; -import { solidRouterBrowserTracingIntegration } from '@sentry/solidstart/solidrouter'; import { redirect } from '@solidjs/router'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { solidRouterBrowserTracingIntegration } from '../../src/client/solidrouter'; const mockCaptureException = vi.spyOn(SentryNode, 'captureException').mockImplementation(() => ''); const mockFlush = vi.spyOn(SentryNode, 'flush').mockImplementation(async () => true); diff --git a/packages/solidstart/test/vite/sentrySolidStartVite.test.ts b/packages/solidstart/test/vite/sentrySolidStartVite.test.ts new file mode 100644 index 000000000000..76b81fff3edd --- /dev/null +++ b/packages/solidstart/test/vite/sentrySolidStartVite.test.ts @@ -0,0 +1,53 @@ +import type { Plugin } from 'vite'; +import { describe, expect, it, vi } from 'vitest'; +import { sentrySolidStartVite } from '../../src/vite/sentrySolidStartVite'; + +vi.spyOn(console, 'log').mockImplementation(() => { + /* noop */ +}); +vi.spyOn(console, 'warn').mockImplementation(() => { + /* noop */ +}); + +function getSentrySolidStartVitePlugins(options?: Parameters[0]): Plugin[] { + return sentrySolidStartVite({ + sourceMapsUploadOptions: { + authToken: 'token', + org: 'org', + project: 'project', + ...options?.sourceMapsUploadOptions, + }, + ...options, + }); +} + +describe('sentrySolidStartVite()', () => { + it('returns an array of vite plugins', () => { + const plugins = getSentrySolidStartVitePlugins(); + const names = plugins.map(plugin => plugin.name); + expect(names).toEqual([ + 'sentry-solidstart-source-maps', + 'sentry-telemetry-plugin', + 'sentry-vite-release-injection-plugin', + 'sentry-debug-id-upload-plugin', + 'sentry-vite-debug-id-injection-plugin', + 'sentry-file-deletion-plugin', + 'sentry-vite-debug-id-upload-plugin', + ]); + }); + + it("returns an empty array if source maps upload isn't enabled", () => { + const plugins = getSentrySolidStartVitePlugins({ sourceMapsUploadOptions: { enabled: false } }); + expect(plugins).toHaveLength(0); + }); + + it('returns an empty array if `NODE_ENV` is development', async () => { + const previousEnv = process.env.NODE_ENV; + process.env.NODE_ENV = 'development'; + + const plugins = getSentrySolidStartVitePlugins({ sourceMapsUploadOptions: { enabled: true } }); + expect(plugins).toHaveLength(0); + + process.env.NODE_ENV = previousEnv; + }); +}); diff --git a/packages/solidstart/test/vite/sourceMaps.test.ts b/packages/solidstart/test/vite/sourceMaps.test.ts new file mode 100644 index 000000000000..7aea5bb24978 --- /dev/null +++ b/packages/solidstart/test/vite/sourceMaps.test.ts @@ -0,0 +1,58 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { makeSourceMapsVitePlugin } from '../../src/vite/sourceMaps'; +import * as sourceMaps from '../../src/vite/sourceMaps'; + +const mockedSentryVitePlugin = { + name: 'sentry-vite-debug-id-upload-plugin', + writeBundle: vi.fn(), +}; + +vi.mock('@sentry/vite-plugin', async () => { + const original = (await vi.importActual('@sentry/vite-plugin')) as any; + + return { + ...original, + sentryVitePlugin: () => [mockedSentryVitePlugin], + }; +}); + +beforeEach(() => { + vi.clearAllMocks(); +}); + +describe('makeSourceMapsVitePlugin()', () => { + it('returns a plugin to set `sourcemaps` to `true`', async () => { + const [sourceMapsConfigPlugin, sentryVitePlugin] = makeSourceMapsVitePlugin({}); + + expect(sourceMapsConfigPlugin?.name).toEqual('sentry-solidstart-source-maps'); + expect(sourceMapsConfigPlugin?.apply).toEqual('build'); + expect(sourceMapsConfigPlugin?.enforce).toEqual('post'); + expect(sourceMapsConfigPlugin?.config).toEqual(expect.any(Function)); + + expect(sentryVitePlugin).toEqual(mockedSentryVitePlugin); + }); + + it('passes user-specified vite plugin options to vite plugin plugin', async () => { + const makePluginSpy = vi.spyOn(sourceMaps, 'makeSourceMapsVitePlugin'); + + makeSourceMapsVitePlugin({ + org: 'my-org', + authToken: 'my-token', + sourcemaps: { + assets: ['foo/*.js'], + ignore: ['bar/*.js'], + filesToDeleteAfterUpload: ['baz/*.js'], + }, + }); + + expect(makePluginSpy).toHaveBeenCalledWith({ + org: 'my-org', + authToken: 'my-token', + sourcemaps: { + assets: ['foo/*.js'], + ignore: ['bar/*.js'], + filesToDeleteAfterUpload: ['baz/*.js'], + }, + }); + }); +}); From 54726a1c8f5261d8518fd4428020fb06502e7e44 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Wed, 28 Aug 2024 13:54:47 +0200 Subject: [PATCH 02/15] Expose `unstable_sentryVitePluginOptions` as escape hatch for `@sentry/vite-plugin` --- packages/solidstart/src/vite/sourceMaps.ts | 2 + packages/solidstart/src/vite/types.ts | 17 +++++++ .../solidstart/test/vite/sourceMaps.test.ts | 46 +++++++++++++++---- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/packages/solidstart/src/vite/sourceMaps.ts b/packages/solidstart/src/vite/sourceMaps.ts index 2133edbfa9dd..3a3afd187ae3 100644 --- a/packages/solidstart/src/vite/sourceMaps.ts +++ b/packages/solidstart/src/vite/sourceMaps.ts @@ -44,6 +44,7 @@ export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { assets: options.sourcemaps?.assets ?? undefined, ignore: options.sourcemaps?.ignore ?? undefined, filesToDeleteAfterUpload: options.sourcemaps?.filesToDeleteAfterUpload ?? undefined, + ...options.unstable_sentryVitePluginOptions?.sourcemaps, }, _metaOptions: { telemetry: { @@ -51,6 +52,7 @@ export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { }, }, debug: options.debug ?? false, + ...options.unstable_sentryVitePluginOptions, }), ]; } diff --git a/packages/solidstart/src/vite/types.ts b/packages/solidstart/src/vite/types.ts index 0a1c6dc81acb..8d595be1a54d 100644 --- a/packages/solidstart/src/vite/types.ts +++ b/packages/solidstart/src/vite/types.ts @@ -1,3 +1,5 @@ +import type { SentryVitePluginOptions } from '@sentry/vite-plugin'; + export type SourceMapsOptions = { /** * If this flag is `true`, and an auth token is detected, the Sentry SDK will @@ -70,6 +72,21 @@ export type SourceMapsOptions = { filesToDeleteAfterUpload?: string | Array; }; + /** + * Options to further customize the Sentry Vite Plugin (@sentry/vite-plugin) behavior directly. + * Options specified in this object take precedence over the options specified in + * the `sourcemaps` and `release` objects. + * + * @see https://www.npmjs.com/package/@sentry/vite-plugin/v/2.22.2#options which lists all available options. + * + * Warning: Options within this object are subject to change at any time. + * We DO NOT guarantee semantic versioning for these options, meaning breaking + * changes can occur at any time within a major SDK version. + * + * Furthermore, some options are untested with SvelteKit specifically. Use with caution. + */ + unstable_sentryVitePluginOptions?: Partial; + /** * Enable debug functionality of the SDK during build-time. * Enabling this will give you logs about source maps. diff --git a/packages/solidstart/test/vite/sourceMaps.test.ts b/packages/solidstart/test/vite/sourceMaps.test.ts index 7aea5bb24978..d1e8d3f4633c 100644 --- a/packages/solidstart/test/vite/sourceMaps.test.ts +++ b/packages/solidstart/test/vite/sourceMaps.test.ts @@ -1,18 +1,20 @@ +import { SentryVitePluginOptions } from '@sentry/vite-plugin'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { makeSourceMapsVitePlugin } from '../../src/vite/sourceMaps'; -import * as sourceMaps from '../../src/vite/sourceMaps'; const mockedSentryVitePlugin = { name: 'sentry-vite-debug-id-upload-plugin', writeBundle: vi.fn(), }; +const sentryVitePluginSpy = vi.fn((_options: SentryVitePluginOptions) => [mockedSentryVitePlugin]); + vi.mock('@sentry/vite-plugin', async () => { const original = (await vi.importActual('@sentry/vite-plugin')) as any; return { ...original, - sentryVitePlugin: () => [mockedSentryVitePlugin], + sentryVitePlugin: (options: SentryVitePluginOptions) => sentryVitePluginSpy(options), }; }); @@ -21,7 +23,7 @@ beforeEach(() => { }); describe('makeSourceMapsVitePlugin()', () => { - it('returns a plugin to set `sourcemaps` to `true`', async () => { + it('returns a plugin to set `sourcemaps` to `true`', () => { const [sourceMapsConfigPlugin, sentryVitePlugin] = makeSourceMapsVitePlugin({}); expect(sourceMapsConfigPlugin?.name).toEqual('sentry-solidstart-source-maps'); @@ -32,9 +34,7 @@ describe('makeSourceMapsVitePlugin()', () => { expect(sentryVitePlugin).toEqual(mockedSentryVitePlugin); }); - it('passes user-specified vite plugin options to vite plugin plugin', async () => { - const makePluginSpy = vi.spyOn(sourceMaps, 'makeSourceMapsVitePlugin'); - + it('passes user-specified vite plugin options to vite plugin plugin', () => { makeSourceMapsVitePlugin({ org: 'my-org', authToken: 'my-token', @@ -45,14 +45,42 @@ describe('makeSourceMapsVitePlugin()', () => { }, }); - expect(makePluginSpy).toHaveBeenCalledWith({ + expect(sentryVitePluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ + org: 'my-org', + authToken: 'my-token', + sourcemaps: { + assets: ['foo/*.js'], + ignore: ['bar/*.js'], + filesToDeleteAfterUpload: ['baz/*.js'], + }, + }), + ); + }); + + it('should override options with unstable_sentryVitePluginOptions', () => { + makeSourceMapsVitePlugin({ org: 'my-org', authToken: 'my-token', sourcemaps: { assets: ['foo/*.js'], - ignore: ['bar/*.js'], - filesToDeleteAfterUpload: ['baz/*.js'], + }, + unstable_sentryVitePluginOptions: { + org: 'unstable-org', + sourcemaps: { + assets: ['unstable/*.js'], + }, }, }); + + expect(sentryVitePluginSpy).toHaveBeenCalledWith( + expect.objectContaining({ + org: 'unstable-org', + authToken: 'my-token', + sourcemaps: { + assets: ['unstable/*.js'], + }, + }), + ); }); }); From 453b6dc9e8313ceb29e5307eb5d4b6af039b5e1e Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Wed, 28 Aug 2024 15:34:10 +0200 Subject: [PATCH 03/15] Flatten options, remove fields that will get auto-picked up --- packages/solidstart/src/vite/sourceMaps.ts | 8 ++-- packages/solidstart/src/vite/types.ts | 37 ++++--------------- .../solidstart/test/vite/sourceMaps.test.ts | 2 +- 3 files changed, 11 insertions(+), 36 deletions(-) diff --git a/packages/solidstart/src/vite/sourceMaps.ts b/packages/solidstart/src/vite/sourceMaps.ts index 3a3afd187ae3..b9d80a56461b 100644 --- a/packages/solidstart/src/vite/sourceMaps.ts +++ b/packages/solidstart/src/vite/sourceMaps.ts @@ -18,10 +18,10 @@ export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { if (options.debug && sourceMapsPreviouslyNotEnabled) { // eslint-disable-next-line no-console console.log('[Sentry SolidStart Plugin] Enabling source map generation'); - if (!options.sourcemaps?.filesToDeleteAfterUpload) { + if (!options.filesToDeleteAfterUpload) { // eslint-disable-next-line no-console console.warn( - `[Sentry SolidStart PLugin] We recommend setting the \`sourceMapsUploadOptions.sourcemaps.filesToDeleteAfterUpload\` option to clean up source maps after uploading. + `[Sentry SolidStart PLugin] We recommend setting the \`sourceMapsUploadOptions.filesToDeleteAfterUpload\` option to clean up source maps after uploading. [Sentry SolidStart Plugin] Otherwise, source maps might be deployed to production, depending on your configuration`, ); } @@ -41,9 +41,7 @@ export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { authToken: options.authToken ?? process.env.SENTRY_AUTH_TOKEN, telemetry: options.telemetry ?? true, sourcemaps: { - assets: options.sourcemaps?.assets ?? undefined, - ignore: options.sourcemaps?.ignore ?? undefined, - filesToDeleteAfterUpload: options.sourcemaps?.filesToDeleteAfterUpload ?? undefined, + filesToDeleteAfterUpload: options.filesToDeleteAfterUpload ?? undefined, ...options.unstable_sentryVitePluginOptions?.sourcemaps, }, _metaOptions: { diff --git a/packages/solidstart/src/vite/types.ts b/packages/solidstart/src/vite/types.ts index 8d595be1a54d..85043b6520fb 100644 --- a/packages/solidstart/src/vite/types.ts +++ b/packages/solidstart/src/vite/types.ts @@ -40,37 +40,14 @@ export type SourceMapsOptions = { telemetry?: boolean; /** - * Options related to sourcemaps + * A glob or an array of globs that specifies the build artifacts that should be deleted after the artifact + * upload to Sentry has been completed. + * + * @default [] - By default no files are deleted. + * + * The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob) */ - sourcemaps?: { - /** - * A glob or an array of globs that specify the build artifacts and source maps that will be uploaded to Sentry. - * - * The globbing patterns must follow the implementation of the `glob` package. - * @see https://www.npmjs.com/package/glob#glob-primer - */ - assets?: string | Array; - - /** - * A glob or an array of globs that specifies which build artifacts should not be uploaded to Sentry. - * - * @default [] - By default no files are ignored. Thus, all files matching the `assets` glob - * or the default value for `assets` are uploaded. - * - * The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob) - */ - ignore?: string | Array; - - /** - * A glob or an array of globs that specifies the build artifacts that should be deleted after the artifact - * upload to Sentry has been completed. - * - * @default [] - By default no files are deleted. - * - * The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob) - */ - filesToDeleteAfterUpload?: string | Array; - }; + filesToDeleteAfterUpload?: string | Array; /** * Options to further customize the Sentry Vite Plugin (@sentry/vite-plugin) behavior directly. diff --git a/packages/solidstart/test/vite/sourceMaps.test.ts b/packages/solidstart/test/vite/sourceMaps.test.ts index d1e8d3f4633c..168d01b34793 100644 --- a/packages/solidstart/test/vite/sourceMaps.test.ts +++ b/packages/solidstart/test/vite/sourceMaps.test.ts @@ -1,4 +1,4 @@ -import { SentryVitePluginOptions } from '@sentry/vite-plugin'; +import type { SentryVitePluginOptions } from '@sentry/vite-plugin'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { makeSourceMapsVitePlugin } from '../../src/vite/sourceMaps'; From 0e84d9459b9afcfb238805752c14e74edb883850 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Wed, 28 Aug 2024 15:54:52 +0200 Subject: [PATCH 04/15] Fix unit test --- packages/solidstart/test/vite/sourceMaps.test.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/solidstart/test/vite/sourceMaps.test.ts b/packages/solidstart/test/vite/sourceMaps.test.ts index 168d01b34793..504d1aea9380 100644 --- a/packages/solidstart/test/vite/sourceMaps.test.ts +++ b/packages/solidstart/test/vite/sourceMaps.test.ts @@ -38,11 +38,7 @@ describe('makeSourceMapsVitePlugin()', () => { makeSourceMapsVitePlugin({ org: 'my-org', authToken: 'my-token', - sourcemaps: { - assets: ['foo/*.js'], - ignore: ['bar/*.js'], - filesToDeleteAfterUpload: ['baz/*.js'], - }, + filesToDeleteAfterUpload: ['baz/*.js'], }); expect(sentryVitePluginSpy).toHaveBeenCalledWith( @@ -50,8 +46,6 @@ describe('makeSourceMapsVitePlugin()', () => { org: 'my-org', authToken: 'my-token', sourcemaps: { - assets: ['foo/*.js'], - ignore: ['bar/*.js'], filesToDeleteAfterUpload: ['baz/*.js'], }, }), @@ -62,9 +56,6 @@ describe('makeSourceMapsVitePlugin()', () => { makeSourceMapsVitePlugin({ org: 'my-org', authToken: 'my-token', - sourcemaps: { - assets: ['foo/*.js'], - }, unstable_sentryVitePluginOptions: { org: 'unstable-org', sourcemaps: { From 8461d44a3e26c565fa20421d103ea93cca6aeacd Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Wed, 28 Aug 2024 18:53:55 +0200 Subject: [PATCH 05/15] Remove madge check for middleware --- packages/solidstart/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index c829c8b6d1a5..df8428a8bc12 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -106,7 +106,7 @@ "build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch", "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:tarball": "npm pack", - "circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts && madge --circular src/solidrouter.client.ts && madge --circular src/solidrouter.server.ts && madge --circular src/solidrouter.ts && madge --circular src/middleware.ts", + "circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts && madge --circular src/solidrouter.client.ts && madge --circular src/solidrouter.server.ts && madge --circular src/solidrouter.ts", "clean": "rimraf build coverage sentry-solidstart-*.tgz ./*.d.ts ./*.d.ts.map ./client ./server", "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", From 330270b29694d1de3c588cd6671141cae180e146 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Wed, 28 Aug 2024 19:02:38 +0200 Subject: [PATCH 06/15] Lint README --- packages/solidstart/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/solidstart/README.md b/packages/solidstart/README.md index cf6c393c407a..3b7b1fbb71e6 100644 --- a/packages/solidstart/README.md +++ b/packages/solidstart/README.md @@ -159,8 +159,8 @@ render( ## Uploading Source Maps -To upload source maps, add the `sentrySolidStartVite` plugin from `@sentry/solidstart` to your `app.config.ts` and configure -an auth token. Auth tokens can be passed to the plugin explicitly with the `authToken` option, with a +To upload source maps, add the `sentrySolidStartVite` plugin from `@sentry/solidstart` to your `app.config.ts` and +configure an auth token. Auth tokens can be passed to the plugin explicitly with the `authToken` option, with a `SENTRY_AUTH_TOKEN` environment variable, or with an `.env.sentry-build-plugin` file in the working directory when building your project. We recommend you add the auth token to your CI/CD environment as an environment variable. From 8142b06ffea15cbe145192517b08286467e26e58 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Wed, 28 Aug 2024 19:11:03 +0200 Subject: [PATCH 07/15] Fix ordering of plugins test --- packages/solidstart/test/vite/sentrySolidStartVite.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/solidstart/test/vite/sentrySolidStartVite.test.ts b/packages/solidstart/test/vite/sentrySolidStartVite.test.ts index 76b81fff3edd..81d0d4af8d5a 100644 --- a/packages/solidstart/test/vite/sentrySolidStartVite.test.ts +++ b/packages/solidstart/test/vite/sentrySolidStartVite.test.ts @@ -31,8 +31,8 @@ describe('sentrySolidStartVite()', () => { 'sentry-vite-release-injection-plugin', 'sentry-debug-id-upload-plugin', 'sentry-vite-debug-id-injection-plugin', - 'sentry-file-deletion-plugin', 'sentry-vite-debug-id-upload-plugin', + 'sentry-file-deletion-plugin', ]); }); From 7c2591c17bba3ff276807a553b0ab8d6557e420a Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Wed, 28 Aug 2024 19:54:55 +0200 Subject: [PATCH 08/15] Remove middleware export --- packages/solidstart/package.json | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index df8428a8bc12..80de3c6b5b36 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -39,17 +39,6 @@ "require": "./build/cjs/index.server.js" } }, - "./middleware": { - "types": "./middleware.d.ts", - "import": { - "types": "./middleware.d.ts", - "default": "./build/esm/middleware.js" - }, - "require": { - "types": "./middleware.d.ts", - "default": "./build/cjs/middleware.js" - } - }, "./solidrouter": { "types": "./solidrouter.d.ts", "browser": { From ecd7a478fe3793c423e63d4742fde33862c76b05 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 29 Aug 2024 10:19:19 +0200 Subject: [PATCH 09/15] Flatten and simplify options --- .../src/vite/sentrySolidStartVite.ts | 2 +- packages/solidstart/src/vite/sourceMaps.ts | 25 +++++----- packages/solidstart/src/vite/types.ts | 50 ++++++++----------- .../test/vite/sentrySolidStartVite.test.ts | 9 ++-- .../solidstart/test/vite/sourceMaps.test.ts | 14 ++++-- 5 files changed, 48 insertions(+), 52 deletions(-) diff --git a/packages/solidstart/src/vite/sentrySolidStartVite.ts b/packages/solidstart/src/vite/sentrySolidStartVite.ts index 28c1125a47b2..7b6b377e075d 100644 --- a/packages/solidstart/src/vite/sentrySolidStartVite.ts +++ b/packages/solidstart/src/vite/sentrySolidStartVite.ts @@ -10,7 +10,7 @@ export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions): Pl if (process.env.NODE_ENV !== 'development') { if (options.sourceMapsUploadOptions?.enabled ?? true) { - sentryPlugins.push(...makeSourceMapsVitePlugin({ ...options.sourceMapsUploadOptions, debug: options.debug })); + sentryPlugins.push(...makeSourceMapsVitePlugin(options)); } } diff --git a/packages/solidstart/src/vite/sourceMaps.ts b/packages/solidstart/src/vite/sourceMaps.ts index b9d80a56461b..d596bb7ab001 100644 --- a/packages/solidstart/src/vite/sourceMaps.ts +++ b/packages/solidstart/src/vite/sourceMaps.ts @@ -1,13 +1,14 @@ import { sentryVitePlugin } from '@sentry/vite-plugin'; import type { Plugin } from 'vite'; -import type { SourceMapsOptions } from './types'; +import type { SentrySolidStartPluginOptions } from './types'; /** * A Sentry plugin for SolidStart to enable source maps and use * @sentry/vite-plugin to automatically upload source maps to Sentry. * @param {SourceMapsOptions} options */ -export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { +export function makeSourceMapsVitePlugin(options: SentrySolidStartPluginOptions): Plugin[] { + const { authToken, debug, org, project, sourceMapsUploadOptions } = options; return [ { name: 'sentry-solidstart-source-maps', @@ -15,10 +16,10 @@ export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { enforce: 'post', config(config) { const sourceMapsPreviouslyNotEnabled = !config.build?.sourcemap; - if (options.debug && sourceMapsPreviouslyNotEnabled) { + if (debug && sourceMapsPreviouslyNotEnabled) { // eslint-disable-next-line no-console console.log('[Sentry SolidStart Plugin] Enabling source map generation'); - if (!options.filesToDeleteAfterUpload) { + if (!sourceMapsUploadOptions?.filesToDeleteAfterUpload) { // eslint-disable-next-line no-console console.warn( `[Sentry SolidStart PLugin] We recommend setting the \`sourceMapsUploadOptions.filesToDeleteAfterUpload\` option to clean up source maps after uploading. @@ -36,21 +37,21 @@ export function makeSourceMapsVitePlugin(options: SourceMapsOptions): Plugin[] { }, }, ...sentryVitePlugin({ - org: options.org ?? process.env.SENTRY_ORG, - project: options.project ?? process.env.SENTRY_PROJECT, - authToken: options.authToken ?? process.env.SENTRY_AUTH_TOKEN, - telemetry: options.telemetry ?? true, + org: org ?? process.env.SENTRY_ORG, + project: project ?? process.env.SENTRY_PROJECT, + authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN, + telemetry: sourceMapsUploadOptions?.telemetry ?? true, sourcemaps: { - filesToDeleteAfterUpload: options.filesToDeleteAfterUpload ?? undefined, - ...options.unstable_sentryVitePluginOptions?.sourcemaps, + filesToDeleteAfterUpload: sourceMapsUploadOptions?.filesToDeleteAfterUpload ?? undefined, + ...sourceMapsUploadOptions?.unstable_sentryVitePluginOptions?.sourcemaps, }, _metaOptions: { telemetry: { metaFramework: 'solidstart', }, }, - debug: options.debug ?? false, - ...options.unstable_sentryVitePluginOptions, + debug: debug ?? false, + ...sourceMapsUploadOptions?.unstable_sentryVitePluginOptions, }), ]; } diff --git a/packages/solidstart/src/vite/types.ts b/packages/solidstart/src/vite/types.ts index 85043b6520fb..f8dad65630fc 100644 --- a/packages/solidstart/src/vite/types.ts +++ b/packages/solidstart/src/vite/types.ts @@ -9,28 +9,6 @@ export type SourceMapsOptions = { */ enabled?: boolean; - /** - * The auth token to use when uploading source maps to Sentry. - * - * Instead of specifying this option, you can also set the `SENTRY_AUTH_TOKEN` environment variable. - * - * To create an auth token, follow this guide: - * @see https://docs.sentry.io/product/accounts/auth-tokens/#organization-auth-tokens - */ - authToken?: string; - - /** - * The organization slug of your Sentry organization. - * Instead of specifying this option, you can also set the `SENTRY_ORG` environment variable. - */ - org?: string; - - /** - * The project slug of your Sentry project. - * Instead of specifying this option, you can also set the `SENTRY_PROJECT` environment variable. - */ - project?: string; - /** * If this flag is `true`, the Sentry plugin will collect some telemetry data and send it to Sentry. * It will not collect any sensitive or user-specific data. @@ -63,18 +41,34 @@ export type SourceMapsOptions = { * Furthermore, some options are untested with SvelteKit specifically. Use with caution. */ unstable_sentryVitePluginOptions?: Partial; - - /** - * Enable debug functionality of the SDK during build-time. - * Enabling this will give you logs about source maps. - */ - debug?: boolean; }; /** * Build options for the Sentry module. These options are used during build-time by the Sentry SDK. */ export type SentrySolidStartPluginOptions = { + /** + * The auth token to use when uploading source maps to Sentry. + * + * Instead of specifying this option, you can also set the `SENTRY_AUTH_TOKEN` environment variable. + * + * To create an auth token, follow this guide: + * @see https://docs.sentry.io/product/accounts/auth-tokens/#organization-auth-tokens + */ + authToken?: string; + + /** + * The organization slug of your Sentry organization. + * Instead of specifying this option, you can also set the `SENTRY_ORG` environment variable. + */ + org?: string; + + /** + * The project slug of your Sentry project. + * Instead of specifying this option, you can also set the `SENTRY_PROJECT` environment variable. + */ + project?: string; + /** * Options for the Sentry Vite plugin to customize the source maps upload process. */ diff --git a/packages/solidstart/test/vite/sentrySolidStartVite.test.ts b/packages/solidstart/test/vite/sentrySolidStartVite.test.ts index 81d0d4af8d5a..d3f905313859 100644 --- a/packages/solidstart/test/vite/sentrySolidStartVite.test.ts +++ b/packages/solidstart/test/vite/sentrySolidStartVite.test.ts @@ -11,12 +11,9 @@ vi.spyOn(console, 'warn').mockImplementation(() => { function getSentrySolidStartVitePlugins(options?: Parameters[0]): Plugin[] { return sentrySolidStartVite({ - sourceMapsUploadOptions: { - authToken: 'token', - org: 'org', - project: 'project', - ...options?.sourceMapsUploadOptions, - }, + project: 'project', + org: 'org', + authToken: 'token', ...options, }); } diff --git a/packages/solidstart/test/vite/sourceMaps.test.ts b/packages/solidstart/test/vite/sourceMaps.test.ts index 504d1aea9380..a70261a0a8ee 100644 --- a/packages/solidstart/test/vite/sourceMaps.test.ts +++ b/packages/solidstart/test/vite/sourceMaps.test.ts @@ -38,7 +38,9 @@ describe('makeSourceMapsVitePlugin()', () => { makeSourceMapsVitePlugin({ org: 'my-org', authToken: 'my-token', - filesToDeleteAfterUpload: ['baz/*.js'], + sourceMapsUploadOptions: { + filesToDeleteAfterUpload: ['baz/*.js'], + }, }); expect(sentryVitePluginSpy).toHaveBeenCalledWith( @@ -56,10 +58,12 @@ describe('makeSourceMapsVitePlugin()', () => { makeSourceMapsVitePlugin({ org: 'my-org', authToken: 'my-token', - unstable_sentryVitePluginOptions: { - org: 'unstable-org', - sourcemaps: { - assets: ['unstable/*.js'], + sourceMapsUploadOptions: { + unstable_sentryVitePluginOptions: { + org: 'unstable-org', + sourcemaps: { + assets: ['unstable/*.js'], + }, }, }, }); From 8576117348b4d272f2083adc6d7b35576dfedf20 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 29 Aug 2024 10:30:06 +0200 Subject: [PATCH 10/15] Update README to reflect plugin option changes --- .github/workflows/build.yml | 2 +- .../solidstart/src/routes/client-error.tsx | 82 +++---------------- .../solidstart/src/routes/error-boundary.tsx | 64 +++++++++++++++ .../solidstart/src/routes/index.tsx | 3 + .../solidstart/tests/errorboundary.test.ts | 10 +-- .../solidstart/tests/errors.client.test.ts | 4 +- packages/solidstart/README.md | 8 +- .../withServerActionInstrumentation.test.ts | 2 - 8 files changed, 89 insertions(+), 86 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/src/routes/error-boundary.tsx diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77ddae4705b6..70535bd06e89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1003,7 +1003,7 @@ jobs: working-directory: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }} timeout-minutes: 5 run: pnpm test:assert - + - name: Upload Playwright Traces uses: actions/upload-artifact@v4 if: failure() diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx index e997e4fbb1e3..5e405e8c4e40 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx @@ -1,75 +1,15 @@ -import * as Sentry from '@sentry/solidstart'; -import type { ParentProps } from 'solid-js'; -import { ErrorBoundary, createSignal, onMount } from 'solid-js'; - -const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary); - -const [count, setCount] = createSignal(1); -const [caughtError, setCaughtError] = createSignal(false); - export default function ClientErrorPage() { return ( - - {caughtError() && ( - - )} -
-
- -
-
- -
-
-
- ); -} - -function Throw(props: { error: string }) { - onMount(() => { - throw new Error(props.error); - }); - return null; -} - -function SampleErrorBoundary(props: ParentProps) { - return ( - ( -
-

Error Boundary Fallback

-
- {error.message} -
- -
- )} - > - {props.children} -
+
+ +
); } diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/routes/error-boundary.tsx b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/error-boundary.tsx new file mode 100644 index 000000000000..b22607667e7e --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/error-boundary.tsx @@ -0,0 +1,64 @@ +import * as Sentry from '@sentry/solidstart'; +import type { ParentProps } from 'solid-js'; +import { ErrorBoundary, createSignal, onMount } from 'solid-js'; + +const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary); + +const [count, setCount] = createSignal(1); +const [caughtError, setCaughtError] = createSignal(false); + +export default function ErrorBoundaryTestPage() { + return ( + + {caughtError() && ( + + )} +
+
+ +
+
+
+ ); +} + +function Throw(props: { error: string }) { + onMount(() => { + throw new Error(props.error); + }); + return null; +} + +function SampleErrorBoundary(props: ParentProps) { + return ( + ( +
+

Error Boundary Fallback

+
+ {error.message} +
+ +
+ )} + > + {props.children} +
+ ); +} diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx index eed722cba4e3..9a0b22cc38c6 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx @@ -14,6 +14,9 @@ export default function Home() {
  • Server error
  • +
  • + Error Boundary +
  • User 5 diff --git a/dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts b/dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts index a4edf3c46236..b709760aab94 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts +++ b/dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts @@ -10,7 +10,7 @@ test('captures an exception', async ({ page }) => { ); }); - await page.goto('/client-error'); + await page.goto('/error-boundary'); await page.locator('#caughtErrorBtn').click(); const errorEvent = await errorEventPromise; @@ -27,7 +27,7 @@ test('captures an exception', async ({ page }) => { }, ], }, - transaction: '/client-error', + transaction: '/error-boundary', }); }); @@ -40,7 +40,7 @@ test('captures a second exception after resetting the boundary', async ({ page } ); }); - await page.goto('/client-error'); + await page.goto('/error-boundary'); await page.locator('#caughtErrorBtn').click(); const firstErrorEvent = await firstErrorEventPromise; @@ -57,7 +57,7 @@ test('captures a second exception after resetting the boundary', async ({ page } }, ], }, - transaction: '/client-error', + transaction: '/error-boundary', }); const secondErrorEventPromise = waitForError('solidstart', errorEvent => { @@ -85,6 +85,6 @@ test('captures a second exception after resetting the boundary', async ({ page } }, ], }, - transaction: '/client-error', + transaction: '/error-boundary', }); }); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts index 0f5ef61b365a..48ffbefc025e 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts @@ -4,7 +4,7 @@ import { waitForError } from '@sentry-internal/test-utils'; test.describe('client-side errors', () => { test('captures error thrown on click', async ({ page }) => { const errorPromise = waitForError('solidstart', async errorEvent => { - return errorEvent?.exception?.values?.[0]?.value === 'Error thrown from Solid Start E2E test app'; + return errorEvent?.exception?.values?.[0]?.value === 'Uncaught error thrown from Solid Start E2E test app'; }); await page.goto(`/client-error`); @@ -16,7 +16,7 @@ test.describe('client-side errors', () => { values: [ { type: 'Error', - value: 'Error thrown from Solid Start E2E test app', + value: 'Uncaught error thrown from Solid Start E2E test app', mechanism: { type: 'instrument', handled: false, diff --git a/packages/solidstart/README.md b/packages/solidstart/README.md index 3b7b1fbb71e6..1bb191994c79 100644 --- a/packages/solidstart/README.md +++ b/packages/solidstart/README.md @@ -178,11 +178,9 @@ export default defineConfig({ vite: { plugins: [ sentrySolidStartVite({ - sourceMapsUploadOptions: { - org: process.env.SENTRY_ORG, - project: process.env.SENTRY_PROJECT, - authToken: process.env.SENTRY_AUTH_TOKEN, - }, + org: process.env.SENTRY_ORG, + project: process.env.SENTRY_PROJECT, + authToken: process.env.SENTRY_AUTH_TOKEN, debug: true, }), ], diff --git a/packages/solidstart/test/server/withServerActionInstrumentation.test.ts b/packages/solidstart/test/server/withServerActionInstrumentation.test.ts index 6bc70d30ae07..7e1686e2ccb1 100644 --- a/packages/solidstart/test/server/withServerActionInstrumentation.test.ts +++ b/packages/solidstart/test/server/withServerActionInstrumentation.test.ts @@ -12,7 +12,6 @@ import { import { NodeClient } from '@sentry/node'; import { redirect } from '@solidjs/router'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { solidRouterBrowserTracingIntegration } from '../../src/client/solidrouter'; const mockCaptureException = vi.spyOn(SentryNode, 'captureException').mockImplementation(() => ''); const mockFlush = vi.spyOn(SentryNode, 'flush').mockImplementation(async () => true); @@ -98,7 +97,6 @@ describe('withServerActionInstrumentation', () => { setCurrentClient(client); client.on('spanStart', span => spanStartMock(spanToJSON(span))); - client.addIntegration(solidRouterBrowserTracingIntegration()); await serverActionGetPrefecture(); expect(spanStartMock).toHaveBeenCalledWith( From e7e117cdc50a2b9a52a4cda57c4b6e545ffa3077 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Tue, 3 Sep 2024 15:37:20 +0900 Subject: [PATCH 11/15] Use the plugin in the e2e app --- .../e2e-tests/test-applications/solidstart/app.config.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts b/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts index b3c737efe5ba..1f4d1058b1d5 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts +++ b/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts @@ -1,3 +1,8 @@ +import { sentrySolidStartVite } from '@sentry/solidstart'; import { defineConfig } from '@solidjs/start/config'; -export default defineConfig({}); +export default defineConfig({ + vite: { + plugins: [sentrySolidStartVite({})], + }, +}); From f1222aae613dd35a8efb9c85eab9fb2d6871d098 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 5 Sep 2024 11:59:13 +0900 Subject: [PATCH 12/15] Clean build output before running test --- .../e2e-tests/test-applications/solidstart/package.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/solidstart/package.json b/dev-packages/e2e-tests/test-applications/solidstart/package.json index dfcf8a47402a..e831a14c1f47 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/package.json +++ b/dev-packages/e2e-tests/test-applications/solidstart/package.json @@ -3,14 +3,19 @@ "version": "0.0.0", "scripts": { "clean": "pnpx rimraf node_modules pnpm-lock.yaml .vinxi .output", + "clean:build": "pnpx rimraf .vinxi .output", "dev": "NODE_OPTIONS='--import ./src/instrument.server.mjs' vinxi dev", "build": "vinxi build", "//": [ "We are using `vinxi dev` to start the server because `vinxi start` is experimental and ", "doesn't correctly resolve modules for @sentry/solidstart/solidrouter.", - "This is currently not an issue outside of our repo. See: https://github.com/nksaraf/vinxi/issues/177" + "This is currently not an issue outside of our repo. See: https://github.com/nksaraf/vinxi/issues/177", + "We run the build command to ensure building succeeds. However, keeping", + "build output around slows down the vite dev server when using `@sentry/vite-plugin` so we clear it out", + "before actually running the tests.", + "Cleaning the build output should be removed once we can use `vinxi start`." ], - "preview": "HOST=localhost PORT=3030 NODE_OPTIONS='--import ./src/instrument.server.mjs' vinxi dev", + "preview": "pnpm clean:build && HOST=localhost PORT=3030 NODE_OPTIONS='--import ./src/instrument.server.mjs' vinxi dev", "start": "HOST=localhost PORT=3030 NODE_OPTIONS='--import ./src/instrument.server.mjs' vinxi start", "test:prod": "TEST_ENV=production playwright test", "test:build": "pnpm install && npx playwright install && pnpm build", From 86394b15e0735170f107579cbdb33b0c445b86be Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 5 Sep 2024 14:17:14 +0900 Subject: [PATCH 13/15] feat(solidstart): Add `bundleSizeOptimizations` to `sentrySolidStartVite` plugin --- packages/solidstart/src/vite/sourceMaps.ts | 7 +-- packages/solidstart/src/vite/types.ts | 48 ++++++++++++++++++- .../solidstart/test/vite/sourceMaps.test.ts | 15 ++++++ 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/packages/solidstart/src/vite/sourceMaps.ts b/packages/solidstart/src/vite/sourceMaps.ts index d596bb7ab001..548038515e79 100644 --- a/packages/solidstart/src/vite/sourceMaps.ts +++ b/packages/solidstart/src/vite/sourceMaps.ts @@ -37,20 +37,21 @@ export function makeSourceMapsVitePlugin(options: SentrySolidStartPluginOptions) }, }, ...sentryVitePlugin({ + authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN, + bundleSizeOptimizations: options.bundleSizeOptimizations, + debug: debug ?? false, org: org ?? process.env.SENTRY_ORG, project: project ?? process.env.SENTRY_PROJECT, - authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN, - telemetry: sourceMapsUploadOptions?.telemetry ?? true, sourcemaps: { filesToDeleteAfterUpload: sourceMapsUploadOptions?.filesToDeleteAfterUpload ?? undefined, ...sourceMapsUploadOptions?.unstable_sentryVitePluginOptions?.sourcemaps, }, + telemetry: sourceMapsUploadOptions?.telemetry ?? true, _metaOptions: { telemetry: { metaFramework: 'solidstart', }, }, - debug: debug ?? false, ...sourceMapsUploadOptions?.unstable_sentryVitePluginOptions, }), ]; diff --git a/packages/solidstart/src/vite/types.ts b/packages/solidstart/src/vite/types.ts index f8dad65630fc..4a64e4856b5d 100644 --- a/packages/solidstart/src/vite/types.ts +++ b/packages/solidstart/src/vite/types.ts @@ -1,6 +1,6 @@ import type { SentryVitePluginOptions } from '@sentry/vite-plugin'; -export type SourceMapsOptions = { +type SourceMapsOptions = { /** * If this flag is `true`, and an auth token is detected, the Sentry SDK will * automatically generate and upload source maps to Sentry during a production build. @@ -43,6 +43,47 @@ export type SourceMapsOptions = { unstable_sentryVitePluginOptions?: Partial; }; +type BundleSizeOptimizationOptions = { + /** + * If set to `true`, the plugin will attempt to tree-shake (remove) any debugging code within the Sentry SDK. + * Note that the success of this depends on tree shaking being enabled in your build tooling. + * + * Setting this option to `true` will disable features like the SDK's `debug` option. + */ + excludeDebugStatements?: boolean; + + /** + * If set to true, the plugin will try to tree-shake tracing statements out. + * Note that the success of this depends on tree shaking generally being enabled in your build. + * Attention: DO NOT enable this when you're using any performance monitoring-related SDK features (e.g. Sentry.startSpan()). + */ + excludeTracing?: boolean; + + /** + * If set to `true`, the plugin will attempt to tree-shake (remove) code related to the Sentry SDK's Session Replay Shadow DOM recording functionality. + * Note that the success of this depends on tree shaking being enabled in your build tooling. + * + * This option is safe to be used when you do not want to capture any Shadow DOM activity via Sentry Session Replay. + */ + excludeReplayShadowDom?: boolean; + + /** + * If set to `true`, the plugin will attempt to tree-shake (remove) code related to the Sentry SDK's Session Replay `iframe` recording functionality. + * Note that the success of this depends on tree shaking being enabled in your build tooling. + * + * You can safely do this when you do not want to capture any `iframe` activity via Sentry Session Replay. + */ + excludeReplayIframe?: boolean; + + /** + * If set to `true`, the plugin will attempt to tree-shake (remove) code related to the Sentry SDK's Session Replay's Compression Web Worker. + * Note that the success of this depends on tree shaking being enabled in your build tooling. + * + * **Notice:** You should only do use this option if you manually host a compression worker and configure it in your Sentry Session Replay integration config via the `workerUrl` option. + */ + excludeReplayWorker?: boolean; +}; + /** * Build options for the Sentry module. These options are used during build-time by the Sentry SDK. */ @@ -74,6 +115,11 @@ export type SentrySolidStartPluginOptions = { */ sourceMapsUploadOptions?: SourceMapsOptions; + /** + * Options for the Sentry Vite plugin to customize bundle size optimizations. + */ + bundleSizeOptimizations?: BundleSizeOptimizationOptions; + /** * Enable debug functionality of the SDK during build-time. * Enabling this will give you, for example logs about source maps. diff --git a/packages/solidstart/test/vite/sourceMaps.test.ts b/packages/solidstart/test/vite/sourceMaps.test.ts index a70261a0a8ee..e7d6c1bd598d 100644 --- a/packages/solidstart/test/vite/sourceMaps.test.ts +++ b/packages/solidstart/test/vite/sourceMaps.test.ts @@ -41,6 +41,9 @@ describe('makeSourceMapsVitePlugin()', () => { sourceMapsUploadOptions: { filesToDeleteAfterUpload: ['baz/*.js'], }, + bundleSizeOptimizations: { + excludeTracing: true, + }, }); expect(sentryVitePluginSpy).toHaveBeenCalledWith( @@ -50,6 +53,9 @@ describe('makeSourceMapsVitePlugin()', () => { sourcemaps: { filesToDeleteAfterUpload: ['baz/*.js'], }, + bundleSizeOptimizations: { + excludeTracing: true, + }, }), ); }); @@ -58,12 +64,18 @@ describe('makeSourceMapsVitePlugin()', () => { makeSourceMapsVitePlugin({ org: 'my-org', authToken: 'my-token', + bundleSizeOptimizations: { + excludeTracing: true, + }, sourceMapsUploadOptions: { unstable_sentryVitePluginOptions: { org: 'unstable-org', sourcemaps: { assets: ['unstable/*.js'], }, + bundleSizeOptimizations: { + excludeTracing: false, + }, }, }, }); @@ -72,6 +84,9 @@ describe('makeSourceMapsVitePlugin()', () => { expect.objectContaining({ org: 'unstable-org', authToken: 'my-token', + bundleSizeOptimizations: { + excludeTracing: false, + }, sourcemaps: { assets: ['unstable/*.js'], }, From 13437903cb0b1be21e36260f4efb6fe67fd30436 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 5 Sep 2024 14:48:10 +0900 Subject: [PATCH 14/15] Make e2e test less flaky on CI --- .../test-applications/solidstart/tests/errors.client.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts index 48ffbefc025e..e2b00786f54c 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts @@ -18,7 +18,6 @@ test.describe('client-side errors', () => { type: 'Error', value: 'Uncaught error thrown from Solid Start E2E test app', mechanism: { - type: 'instrument', handled: false, }, }, From 1378828ffd29cd3f7075f9c7f7b194bf46cb8c48 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 5 Sep 2024 17:27:34 +0900 Subject: [PATCH 15/15] Make plugin options optional --- .../e2e-tests/test-applications/solidstart/app.config.ts | 2 +- packages/solidstart/src/vite/sentrySolidStartVite.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts b/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts index 1f4d1058b1d5..0b9a5553fb0a 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts +++ b/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts @@ -3,6 +3,6 @@ import { defineConfig } from '@solidjs/start/config'; export default defineConfig({ vite: { - plugins: [sentrySolidStartVite({})], + plugins: [sentrySolidStartVite()], }, }); diff --git a/packages/solidstart/src/vite/sentrySolidStartVite.ts b/packages/solidstart/src/vite/sentrySolidStartVite.ts index 7b6b377e075d..59435f919071 100644 --- a/packages/solidstart/src/vite/sentrySolidStartVite.ts +++ b/packages/solidstart/src/vite/sentrySolidStartVite.ts @@ -5,7 +5,7 @@ import type { SentrySolidStartPluginOptions } from './types'; /** * Various Sentry vite plugins to be used for SolidStart. */ -export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions): Plugin[] => { +export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions = {}): Plugin[] => { const sentryPlugins: Plugin[] = []; if (process.env.NODE_ENV !== 'development') {