Skip to content

Commit

Permalink
feat!: upgrade to webpack-plugin v2 for making releases
Browse files Browse the repository at this point in the history
BREAKING CHANGE: See migration guide at https://sentry.nuxtjs.org/guide/migration
  • Loading branch information
rchl committed Sep 19, 2023
1 parent 3b57cfb commit 87bca3f
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 135 deletions.
41 changes: 14 additions & 27 deletions docs/content/en/configuration/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,17 @@ The `dsn` is the only option that is required to enable Sentry reporting.
<alert type="info">
`@sentry/webpack-plugin@1` package must be installed manually as a dev dependency to be able to publish releases.
`@sentry/webpack-plugin@2` package must be installed manually as a dev dependency to be able to publish releases.
</alert>
- Type: `Boolean` or [`WebpackPluginOptions`](https://github.com/getsentry/sentry-webpack-plugin)
- Type: `Boolean` or [`SentryWebpackPluginOptions`](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/packages/bundler-plugin-core/src/types.ts)
- Default: `process.env.SENTRY_PUBLISH_RELEASE || false`
- Enables Sentry releases for better debugging using source maps. Uses [@sentry/webpack-plugin](https://github.com/getsentry/sentry-webpack-plugin).
- Enables Sentry releases for better debugging using source maps. Uses [@sentry/webpack-plugin](https://github.com/getsentry/sentry-javascript-bundler-plugins/).
- Publishing releases requires the organization slug, project name and the Sentry authentication token to be provided. Those can be provided either via an object value or [environment variables or a properties file](https://docs.sentry.io/product/cli/configuration/#sentry-cli-working-with-projects). So for example, when using the object value, you'd set `authToken`, `org` and `project` options, and when using the environment variables you'd set `SENTRY_AUTH_TOKEN`, `SENTRY_ORG` and `SENTRY_PROJECT`.
- It's recommended to pass an object value to this option rather than using the boolean `true`. When using the boolean, you have to provide all required options through other means mentioned above.
- The releases are only published when this option is enabled and at the same time you are NOT running in development (`nuxt dev`) mode.
- See https://docs.sentry.io/workflow/releases for more information. Note that the Sentry CLI options mentioned in the documentation typically have a [@sentry/webpack-plugin](https://github.com/getsentry/sentry-webpack-plugin) equivalent.
- See https://docs.sentry.io/workflow/releases for more information. Note that the Sentry CLI options mentioned in the documentation typically have a [@sentry/webpack-plugin](https://github.com/getsentry/sentry-javascript-bundler-plugins/) equivalent.

Example configuration:

Expand All @@ -179,50 +179,37 @@ sentry: {
authToken: '<token>',
org: 'MyCompany',
project: 'my-project',
// Attach commits to the release (requires that the build triggered within a git repository).
setCommits: {
auto: true
release: {
// Attach commits to the release (requires that the build triggered within a git repository).
setCommits: {
auto: true
}
}
}
}
```

Note that the module sets the following defaults when publishing is enabled:

```js
{
include: [], // automatically set at publishing time to relevant paths for the bundles that were built
ignore: [
'node_modules',
'.nuxt/dist/client/img'
],
configFile: '.sentryclirc',
release: '', // defaults to the value of "config.release" which can either be set manually or is determined automatically through `@sentry/cli`
}
```

- Providing custom values for `include` or `ignore` will result in provided values getting appended to default values.
- module by default includes all js/map assets generated during the build step.

### sourceMapStyle

- Type: `String`
- Default: `source-map`
- Only has effect when `publishRelease` is enabled
- Default: `hidden-source-map`
- Only has an effect when `publishRelease` is enabled
- The type of source maps generated when publishing release to Sentry. See https://webpack.js.org/configuration/devtool for a list of available options
- **Note**: Consider using `hidden-source-map` instead. For most people, that should be a better option but due to it being a breaking change, it won't be set as the default until next major release

### disableServerRelease

- Type: `Boolean`
- Default: `process.env.SENTRY_DISABLE_SERVER_RELEASE || false`
- Only has effect when `publishRelease` is enabled
- Only has an effect when `publishRelease` is enabled
- See https://docs.sentry.io/workflow/releases for more information

### disableClientRelease

- Type: `Boolean`
- Default: `process.env.SENTRY_DISABLE_CLIENT_RELEASE || false`
- Only has effect when `publishRelease` is enabled
- Only has an effect when `publishRelease` is enabled
- See https://docs.sentry.io/workflow/releases for more information

### clientIntegrations
Expand Down
2 changes: 1 addition & 1 deletion docs/content/en/getting-started/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ In Typescript or type-checked JavaScript projects, add `@nuxtjs/sentry` to the `
<alert type="info">
The otherwise optional package `@sentry/webpack-plugin@1` has to be installed for types to be fully working.
The otherwise optional package `@sentry/webpack-plugin@2` has to be installed for types to be fully working.
If not using the relevant functionality (`publishRelease` option is not enabled) then this package can be installed as dev-only dependency.
Expand Down
15 changes: 15 additions & 0 deletions docs/content/en/guide/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ category: Guide

Follow this guide to upgrade from one major version to the other.

## Upgrading from v7 to v8

Breaking changes only affect the `publishRelease` and the (related to `publishRelease`) `sourceMapStyle` option.

When using the `publishRelease` option, the `@sentry/webpack-plugin` package needs to be updated from version 1.x to 2.x.

The options supported by the `publishRelease` object have also changed slightly:
- `configFile`, `dryRun`, `include`, `sourcemap` and `urlPrefix` options are no longer supported.
- `setCommits` option moved to `release.setCommits`
- `errorHandler` option signature has changed - see https://sentry.nuxtjs.org/guide/releases

The default value of the `sourceMapStyle` option has changed from `source-map` to `hidden-source-map` since the new version of the webpack plugin can handle source maps without having to reference them directly in the source files.

You can also check the [`@sentry/webpack-plugin` official migration guide](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/MIGRATION.md#upgrading-to-2x) for more information although not everything mentioned there applies to this module.

## Upgrading from v6 to v7

Sentry SDK dependencies updated from v6 to v7. Please read about breaking changes in Sentry SDK's [Upgrading from v6.x to v7.x](https://github.com/getsentry/sentry-javascript/blob/master/MIGRATION.md#upgrading-from-6x-to-7x) document.
Expand Down
8 changes: 4 additions & 4 deletions docs/content/en/guide/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ category: Guide

Follow the following steps to create and publish releases to Sentry.

1. Install the `@sentry/webpack-plugin@1` package as a dev dependency.
2. Enable the [publishRelease](http://localhost:3000/configuration/options#publishrelease) option. Follow the link for mode detailed explanation of available options.
1. Install the `@sentry/webpack-plugin@2` package as a dev dependency.
2. Enable the [publishRelease](/configuration/options#publishrelease) option. Follow the link for mode detailed explanation of available options.

<alert type="info">

Expand All @@ -32,8 +32,8 @@ On error during publishing, the build will be interrupted. If you would instead
sentry: {
publishRelease: {
// other options...
errorHandler(err, invokeErr, compilation) {
compilation.warnings.push(`Sentry Release Error: ${err.message}`);
errorHandler(error) {
console.error(`Sentry Release Error: ${error.message}`);
},
},
}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"release": "release-it",
"test": "yarn prepack && vitest run && yarn lint:fixture && yarn typecheck",
"test:watch": "vitest",
"typecheck": "tsc",
"typecheck": "yarn dev:prepare && tsc",
"coverage": "codecov"
},
"lint-staged": {
Expand Down Expand Up @@ -78,7 +78,7 @@
"@nuxtjs/module-test-utils": "1.6.3",
"@release-it/conventional-changelog": "7.0.0",
"@sentry/profiling-node": "^1.1.2",
"@sentry/webpack-plugin": "1.20.1",
"@sentry/webpack-plugin": "2.7.1",
"@size-limit/file": "^8.2.6",
"@types/hash-sum": "1.0.0",
"@types/lodash.mergewith": "4.6.7",
Expand Down
77 changes: 20 additions & 57 deletions src/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { fileURLToPath } from 'url'
import { resolve, posix } from 'path'
import { resolve } from 'path'
import { defu } from 'defu'
import type { ConsolaInstance } from 'consola'
import type { Configuration as WebpackConfig } from 'webpack'
import type { SentryCliPluginOptions } from '@sentry/webpack-plugin'
import type { SentryWebpackPluginOptions } from '@sentry/webpack-plugin'
import type { Options } from '@sentry/types'
import * as Sentry from '@sentry/node'
import { addPluginTemplate, addTemplate, addWebpackPlugin } from './kit-shim'
import type { Nuxt } from './kit-shim'
import type { ModuleConfiguration } from './types/configuration'
import { clientSentryEnabled, serverSentryEnabled, envToBool, canInitialize } from './utils'
import { clientSentryEnabled, serverSentryEnabled, canInitialize } from './utils'
import { resolveRelease, ResolvedClientOptions, resolveClientOptions, ResolvedServerOptions, resolveServerOptions } from './options'
import type { SentryHandlerProxy } from './options'

Expand Down Expand Up @@ -62,77 +62,40 @@ export async function buildHook (nuxt: Nuxt, moduleOptions: ModuleConfiguration,
}
}

export async function webpackConfigHook (nuxt: Nuxt, webpackConfigs: WebpackConfig[], options: ModuleConfiguration & { publishRelease: SentryCliPluginOptions }, logger: ConsolaInstance): Promise<void> {
export async function webpackConfigHook (nuxt: Nuxt, webpackConfigs: WebpackConfig[], options: ModuleConfiguration, logger: ConsolaInstance): Promise<void> {
let WebpackPlugin: typeof import('@sentry/webpack-plugin')
try {
WebpackPlugin = await (import('@sentry/webpack-plugin').then(m => m.default || m))
} catch {
throw new Error('The "@sentry/webpack-plugin" package must be installed as a dev dependency to use the "publishRelease" option.')
}

const publishRelease: SentryCliPluginOptions = defu({}, options.publishRelease)
const nuxtOptions = nuxt.options

if (!publishRelease.urlPrefix) {
// Set urlPrefix to match resources on the client. That's not technically correct for the server source maps, but it is what it is for now.
if (typeof (nuxtOptions.router.base) === 'string' && typeof (nuxtOptions.build.publicPath) === 'string') {
const publicPath = posix.join(nuxtOptions.router.base, nuxtOptions.build.publicPath)
publishRelease.urlPrefix = publicPath.startsWith('/') ? `~${publicPath}` : publicPath
}
}

if (!Array.isArray(publishRelease.include)) {
const { include } = publishRelease
publishRelease.include = [...(include ? [include] : [])]
const publishRelease: SentryWebpackPluginOptions = defu(options.publishRelease)
if (!publishRelease.sourcemaps) {
publishRelease.sourcemaps = {}
}

const { buildDir } = nuxtOptions

if (!options.disableServerRelease) {
publishRelease.include.push(`${buildDir}/dist/server`)
if (!publishRelease.sourcemaps.ignore) {
publishRelease.sourcemaps.ignore = []
}
if (!options.disableClientRelease) {
publishRelease.include.push(`${buildDir}/dist/client`)
if (!Array.isArray(publishRelease.sourcemaps.ignore)) {
publishRelease.sourcemaps.ignore = [publishRelease.sourcemaps.ignore]
}

publishRelease.release = options.config.release || publishRelease.release || await resolveRelease(options)

if (!publishRelease.release) {
// We've already tried to determine "release" manually using Sentry CLI so to avoid webpack
// plugin crashing, we'll just bail here.
logger.warn('Sentry release will not be published because "config.release" was not set nor it ' +
'was possible to determine it automatically from the repository')
return
publishRelease.release = {}
}

const attachCommits = envToBool(process.env.SENTRY_AUTO_ATTACH_COMMITS)

if (attachCommits) {
publishRelease.setCommits = publishRelease.setCommits || {}

const { setCommits } = publishRelease

if (setCommits.auto === undefined) {
setCommits.auto = true
}

const repo = process.env.SENTRY_RELEASE_REPO || ''

if (repo && setCommits.repo === undefined) {
setCommits.repo = repo
}
publishRelease.release.name = publishRelease.release.name || options.config.release || await resolveRelease(options)
if (!publishRelease.release.name) {
// We've already tried to determine "release" manually using Sentry CLI so to avoid webpack plugin crashing, we'll just bail here.
logger.warn('Sentry release will not be published because "config.release" or "publishRelease.release.name" was not set nor it ' +
'was possible to determine it automatically from the repository.')
return
}

for (const config of webpackConfigs) {
config.devtool = options.sourceMapStyle
config.plugins = config.plugins || []
config.plugins.push(WebpackPlugin.sentryWebpackPlugin(publishRelease))
}

// Add WebpackPlugin to the last build config

const config = webpackConfigs[webpackConfigs.length - 1]

config.plugins = config.plugins || []
config.plugins.push(new WebpackPlugin(publishRelease))
}

export async function initializeServerSentry (nuxt: Nuxt, moduleOptions: ModuleConfiguration, sentryHandlerProxy: SentryHandlerProxy, logger: ConsolaInstance): Promise<void> {
Expand Down
20 changes: 9 additions & 11 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fileURLToPath } from 'url'
import { defu } from 'defu'
import { resolvePath } from 'mlly'
import type { SentryCliPluginOptions } from '@sentry/webpack-plugin'
import type { SentryWebpackPluginOptions } from '@sentry/webpack-plugin'
import { captureException, withScope } from '@sentry/node'
import type { Configuration as WebpackConfig } from 'webpack'
import { defineNuxtModule, isNuxt2, useLogger } from './kit-shim'
Expand Down Expand Up @@ -33,7 +33,7 @@ export default defineNuxtModule<ModuleConfiguration>({
disableServerRelease: envToBool(process.env.SENTRY_DISABLE_SERVER_RELEASE) || false,
disableClientRelease: envToBool(process.env.SENTRY_DISABLE_CLIENT_RELEASE) || false,
logMockCalls: true,
sourceMapStyle: 'source-map',
sourceMapStyle: 'hidden-source-map',
tracing: false,
clientIntegrations: {
ExtraErrorData: {},
Expand All @@ -56,17 +56,15 @@ export default defineNuxtModule<ModuleConfiguration>({
requestHandlerConfig: {},
}),
async setup (options, nuxt) {
const defaultsPublishRelease: SentryCliPluginOptions = {
include: [],
ignore: [
'node_modules',
'.nuxt/dist/client/img',
],
configFile: '.sentryclirc',
const defaultsPublishRelease: SentryWebpackPluginOptions = {
sourcemaps: {
ignore: [
'node_modules/**/*',
],
},
}

if (options.publishRelease) {
// @ts-expect-error Defu introduces "null" value in its merged types which cause error.
options.publishRelease = defu(options.publishRelease, defaultsPublishRelease)
}

Expand Down Expand Up @@ -155,7 +153,7 @@ export default defineNuxtModule<ModuleConfiguration>({
// Enable publishing of sourcemaps
if (options.publishRelease && !options.disabled && !nuxt.options.dev) {
if (isNuxt2()) {
nuxt.hook('webpack:config', (webpackConfigs: WebpackConfig[]) => webpackConfigHook(nuxt, webpackConfigs, options as ModuleConfiguration & { publishRelease: SentryCliPluginOptions }, logger))
nuxt.hook('webpack:config', (webpackConfigs: WebpackConfig[]) => webpackConfigHook(nuxt, webpackConfigs, options, logger))
}
}
},
Expand Down
6 changes: 3 additions & 3 deletions src/types/configuration.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Options as SentryOptions, IntegrationClass } from '@sentry/types'
import * as PluggableIntegrations from '@sentry/integrations'
import { BrowserTracing, Integrations as BrowserIntegrations, Replay, vueRouterInstrumentation } from '@sentry/vue'
import { Options as SentryVueOptions, TracingOptions as SentryVueTracingOptions } from '@sentry/vue/types/types'
import { SentryCliPluginOptions } from '@sentry/webpack-plugin'
import { SentryWebpackPluginOptions } from '@sentry/webpack-plugin'
import { Integrations as NodeIntegrations, NodeOptions, Handlers } from '@sentry/node'

type IntegrationsConfig<T extends Record<keyof T, IntegrationClass<unknown>>> = Partial<{
Expand Down Expand Up @@ -48,8 +48,8 @@ export interface ModuleConfiguration {
initialize: boolean
lazy: boolean | LazyConfiguration
logMockCalls: boolean
/** See available options at https://github.com/getsentry/sentry-webpack-plugin */
publishRelease: boolean | Partial<SentryCliPluginOptions>
/** See available options at https://docs.sentry.io/platforms/node/sourcemaps/uploading/webpack/ */
publishRelease: boolean | SentryWebpackPluginOptions
runtimeConfigKey: string
serverConfig: NodeOptions | string
serverIntegrations: ServerIntegrations
Expand Down
6 changes: 0 additions & 6 deletions test/fixture/default/nuxt.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ const config = {
},
customClientIntegrations: '~/config/custom-client-integrations.js',
tracing: true,
publishRelease: {
authToken: 'fakeToken',
org: 'MyCompany',
project: 'TestProject',
dryRun: true,
},
},
}

Expand Down
Loading

0 comments on commit 87bca3f

Please sign in to comment.