-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(angular): Add Ivy-compatible Angular SDK package (#7264)
Add a new SDK package to our monorepo: `@sentry/angular-ivy`. While this is technically a new SDK, its content and functionality is identical to `@sentry/angular`. Only the build configuration differs: * The Ivy SDK is built with Angular 12, allowing for a compatibility of NG12-15 * The Ivy SDK is built with `compilationMode: partial`, enabeling a build format that is compatible with Angular's Ivy rendering engine. * This means that `ngcc` no longer needs to step in at initial build time to up-compile the SDK. Which is good because `ngcc` will be removed in Angular 16 (angular/angular-cli#24720) * The Ivy SDK's build output follows the Angular Package Format (APF) v12 standard ([spec](https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/preview)) which is very similar to APF 10 which we used before (see #4641 for more details) Because functionality-wise there's no difference to `@sentry/angular`, I opted to symlink the source files instead of duplicating them. The only exception is `sdk.ts` which needed some adaption for the new package, like setting the SDK name and adjusting the min version check. For the same reason, this new package currently doesn't contain tests. We'll need to reconsider this approach (symlinking and testing) if we ever need to make package-specific adjustments.
- Loading branch information
Showing
24 changed files
with
3,309 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module.exports = { | ||
env: { | ||
browser: true, | ||
}, | ||
extends: ['../../.eslintrc.js'], | ||
ignorePatterns: ['scripts/**/*'], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the | ||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit | ||
persons to whom the Software is furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the | ||
Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
<p align="center"> | ||
<a href="https://sentry.io/?utm_source=github&utm_medium=logo" target="_blank"> | ||
<img src="https://sentry-brand.storage.googleapis.com/sentry-wordmark-dark-280x84.png" alt="Sentry" width="280" height="84"> | ||
</a> | ||
</p> | ||
|
||
# Official Sentry SDK for Angular with Ivy Compatibility | ||
|
||
## Links | ||
|
||
- [Official SDK Docs](https://docs.sentry.io/platforms/javascript/angular/) | ||
|
||
## Angular Version Compatibility | ||
|
||
**Note**: This SDK is still experimental and not yet stable. | ||
We do not yet make guarantees in terms of breaking changes, version compatibilities or semver. | ||
Please open a Github issue if you experience bugs or would like to share feedback. | ||
|
||
This SDK officially supports Angular 12-15 with Angular's new rendering engine, Ivy. | ||
|
||
If you're using Angular 10, 11 or a newer Angular version with View Engine instead of Ivy, please use [`@sentry/angular`](https://github.com/getsentry/sentry-javascript/blob/develop/packages/angular/README.md). | ||
|
||
If you're using an older version of Angular and experience problems with the Angular SDK, we recommend downgrading the SDK to version 6.x. | ||
Please note that we don't provide any support for Angular versions below 10. | ||
|
||
## General | ||
|
||
This package is a wrapper around `@sentry/browser`, with added functionality related to Angular. All methods available | ||
in `@sentry/browser` can be imported from `@sentry/angular-ivy`. | ||
|
||
To use this SDK, call `Sentry.init(options)` before you bootstrap your Angular application. | ||
|
||
```javascript | ||
import { enableProdMode } from '@angular/core'; | ||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; | ||
import { init } from '@sentry/angular-ivy'; | ||
|
||
import { AppModule } from './app/app.module'; | ||
|
||
init({ | ||
dsn: '__DSN__', | ||
// ... | ||
}); | ||
|
||
// ... | ||
|
||
enableProdMode(); | ||
platformBrowserDynamic() | ||
.bootstrapModule(AppModule) | ||
.then(success => console.log(`Bootstrap success`)) | ||
.catch(err => console.error(err)); | ||
``` | ||
|
||
### ErrorHandler | ||
|
||
`@sentry/angular-ivy` exports a function to instantiate an ErrorHandler provider that will automatically send Javascript errors | ||
captured by the Angular's error handler. | ||
|
||
```javascript | ||
import { NgModule, ErrorHandler } from '@angular/core'; | ||
import { createErrorHandler } from '@sentry/angular-ivy'; | ||
|
||
@NgModule({ | ||
// ... | ||
providers: [ | ||
{ | ||
provide: ErrorHandler, | ||
useValue: createErrorHandler({ | ||
showDialog: true, | ||
}), | ||
}, | ||
], | ||
// ... | ||
}) | ||
export class AppModule {} | ||
``` | ||
|
||
Additionally, `createErrorHandler` accepts a set of options that allows you to configure its behavior. For more details | ||
see `ErrorHandlerOptions` interface in `src/errorhandler.ts`. | ||
|
||
### Tracing | ||
|
||
`@sentry/angular-ivy` exports a Trace Service, Directive and Decorators that leverage the `@sentry/tracing` Tracing | ||
integration to add Angular related spans to transactions. If the Tracing integration is not enabled, this functionality | ||
will not work. The service itself tracks route changes and durations, where directive and decorators are tracking | ||
components initializations. | ||
|
||
#### Install | ||
|
||
Registering a Trace Service is a 3-step process. | ||
|
||
1. Register and configure the `BrowserTracing` integration from `@sentry/tracing`, including custom Angular routing | ||
instrumentation: | ||
|
||
```javascript | ||
import { init, instrumentAngularRouting } from '@sentry/angular-ivy'; | ||
import { Integrations as TracingIntegrations } from '@sentry/tracing'; | ||
|
||
init({ | ||
dsn: '__DSN__', | ||
integrations: [ | ||
new TracingIntegrations.BrowserTracing({ | ||
tracingOrigins: ['localhost', 'https://yourserver.io/api'], | ||
routingInstrumentation: instrumentAngularRouting, | ||
}), | ||
], | ||
tracesSampleRate: 1, | ||
}); | ||
``` | ||
|
||
2. Register `SentryTrace` as a provider in Angular's DI system, with a `Router` as its dependency: | ||
|
||
```javascript | ||
import { NgModule } from '@angular/core'; | ||
import { Router } from '@angular/router'; | ||
import { TraceService } from '@sentry/angular-ivy'; | ||
|
||
@NgModule({ | ||
// ... | ||
providers: [ | ||
{ | ||
provide: TraceService, | ||
deps: [Router], | ||
}, | ||
], | ||
// ... | ||
}) | ||
export class AppModule {} | ||
``` | ||
|
||
3. Either require the `TraceService` from inside `AppModule` or use `APP_INITIALIZER` to force-instantiate Tracing. | ||
|
||
```javascript | ||
@NgModule({ | ||
// ... | ||
}) | ||
export class AppModule { | ||
constructor(trace: TraceService) {} | ||
} | ||
``` | ||
|
||
or | ||
|
||
```javascript | ||
import { APP_INITIALIZER } from '@angular/core'; | ||
|
||
@NgModule({ | ||
// ... | ||
providers: [ | ||
{ | ||
provide: APP_INITIALIZER, | ||
useFactory: () => () => {}, | ||
deps: [TraceService], | ||
multi: true, | ||
}, | ||
], | ||
// ... | ||
}) | ||
export class AppModule {} | ||
``` | ||
|
||
#### Use | ||
|
||
To track Angular components as part of your transactions, you have 3 options. | ||
|
||
_TraceDirective:_ used to track a duration between `OnInit` and `AfterViewInit` lifecycle hooks in template: | ||
|
||
```javascript | ||
import { TraceModule } from '@sentry/angular-ivy'; | ||
|
||
@NgModule({ | ||
// ... | ||
imports: [TraceModule], | ||
// ... | ||
}) | ||
export class AppModule {} | ||
``` | ||
|
||
Then inside your components template (keep in mind that directive name attribute is required): | ||
|
||
```html | ||
<app-header trace="header"></app-header> | ||
<articles-list trace="articles-list"></articles-list> | ||
<app-footer trace="footer"></app-footer> | ||
``` | ||
|
||
_TraceClassDecorator:_ used to track a duration between `OnInit` and `AfterViewInit` lifecycle hooks in components: | ||
|
||
```javascript | ||
import { Component } from '@angular/core'; | ||
import { TraceClassDecorator } from '@sentry/angular-ivy'; | ||
|
||
@Component({ | ||
selector: 'layout-header', | ||
templateUrl: './header.component.html', | ||
}) | ||
@TraceClassDecorator() | ||
export class HeaderComponent { | ||
// ... | ||
} | ||
``` | ||
|
||
_TraceMethodDecorator:_ used to track a specific lifecycle hooks as point-in-time spans in components: | ||
|
||
```javascript | ||
import { Component, OnInit } from '@angular/core'; | ||
import { TraceMethodDecorator } from '@sentry/angular-ivy'; | ||
|
||
@Component({ | ||
selector: 'app-footer', | ||
templateUrl: './footer.component.html', | ||
}) | ||
export class FooterComponent implements OnInit { | ||
@TraceMethodDecorator() | ||
ngOnInit() {} | ||
} | ||
``` | ||
|
||
You can also add your own custom spans by attaching them to the current active transaction using `getActiveTransaction` | ||
helper. For example, if you'd like to track the duration of Angular boostraping process, you can do it as follows: | ||
|
||
```javascript | ||
import { enableProdMode } from '@angular/core'; | ||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; | ||
import { init, getActiveTransaction } from '@sentry/angular-ivy'; | ||
|
||
import { AppModule } from './app/app.module'; | ||
|
||
// ... | ||
|
||
const activeTransaction = getActiveTransaction(); | ||
const boostrapSpan = | ||
activeTransaction && | ||
activeTransaction.startChild({ | ||
description: 'platform-browser-dynamic', | ||
op: 'ui.angular.bootstrap', | ||
}); | ||
|
||
platformBrowserDynamic() | ||
.bootstrapModule(AppModule) | ||
.then(() => console.log(`Bootstrap success`)) | ||
.catch(err => console.error(err)); | ||
.finally(() => { | ||
if (bootstrapSpan) { | ||
boostrapSpan.finish(); | ||
} | ||
}) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* To learn more about this file see: https://angular.io/guide/workspace-config */ | ||
{ | ||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", | ||
"version": 1, // version of angular.json | ||
"projects": { | ||
"sentry-angular-ivy": { | ||
"projectType": "library", | ||
"root": ".", | ||
"sourceRoot": "src", | ||
"architect": { | ||
"build": { | ||
"builder": "@angular-devkit/build-angular:ng-packagr", | ||
"options": { | ||
"project": "ng-package.json" | ||
}, | ||
"configurations": { | ||
"production": { | ||
"tsConfig": "tsconfig.ngc.json" | ||
}, | ||
"development": { | ||
"tsConfig": "tsconfig.ngc.json" | ||
} | ||
}, | ||
"defaultConfiguration": "production" | ||
} | ||
} | ||
} | ||
}, | ||
"defaultProject": "sentry-angular-ivy" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"$schema": "node_modules/ng-packagr/ng-package.schema.json", | ||
"dest": "build", | ||
"lib": { | ||
"entryFile": "src/index.ts", | ||
"umdModuleIds": { | ||
"@sentry/browser": "Sentry", | ||
"@sentry/utils": "Sentry.util" | ||
} | ||
}, | ||
"allowedNonPeerDependencies": ["@sentry/browser", "@sentry/utils", "@sentry/types", "tslib"], | ||
"assets": ["README.md", "LICENSE"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
{ | ||
"name": "@sentry/angular-ivy", | ||
"version": "7.38.0", | ||
"description": "Official Sentry SDK for Angular with full Ivy Support", | ||
"repository": "git://github.com/getsentry/sentry-javascript.git", | ||
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular-ivy", | ||
"author": "Sentry", | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">=12" | ||
}, | ||
"main": "build/bundles/sentry-angular.umd.js", | ||
"module": "build/fesm2015/sentry-angular.js", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"peerDependencies": { | ||
"@angular/common": ">= 12.x <= 15.x", | ||
"@angular/core": ">= 12.x <= 15.x", | ||
"@angular/router": ">= 12.x <= 15.x", | ||
"rxjs": "^6.5.5 || ^7.x" | ||
}, | ||
"dependencies": { | ||
"@sentry/browser": "7.38.0", | ||
"@sentry/types": "7.38.0", | ||
"@sentry/utils": "7.38.0", | ||
"tslib": "^2.3.0" | ||
}, | ||
"devDependencies": { | ||
"@angular-devkit/build-angular": "~12.2.18", | ||
"@angular/cli": "~12.2.18", | ||
"@angular/common": "~12.2.0", | ||
"@angular/compiler": "~12.2.0", | ||
"@angular/compiler-cli": "~12.2.0", | ||
"@angular/core": "~12.2.0", | ||
"@angular/platform-browser": "~12.2.0", | ||
"@angular/platform-browser-dynamic": "~12.2.0", | ||
"@angular/router": "~12.2.0", | ||
"ng-packagr": "^12.1.1", | ||
"typescript": "~4.3.5", | ||
"zone.js": "~0.11.4" | ||
}, | ||
"scripts": { | ||
"build": "yarn build:syncSymlinks && yarn build:transpile", | ||
"build:transpile": "ng build", | ||
"build:dev": "yarn build", | ||
"build:watch": "yarn build:syncSymlinks && yarn build:transpile:watch", | ||
"build:dev:watch": "yarn build:watch", | ||
"build:transpile:watch": "ng build --watch", | ||
"build:tarball": "npm pack ./build", | ||
"build:syncSymlinks": "ts-node ./scripts/syncSourceFiles.ts", | ||
"circularDepCheck": "madge --circular src/index.ts", | ||
"clean": "rimraf build coverage sentry-angular-ivy-*.tgz", | ||
"fix": "run-s fix:eslint fix:prettier", | ||
"fix:eslint": "eslint . --format stylish --fix", | ||
"fix:prettier": "prettier --write \"{src,test,scripts}/**/**.ts\"", | ||
"lint": "run-s lint:prettier lint:eslint", | ||
"lint:eslint": "eslint . --format stylish", | ||
"lint:prettier": "prettier --check \"{src,test,scripts}/**/**.ts\"" | ||
}, | ||
"volta": { | ||
"extends": "../../package.json" | ||
}, | ||
"sideEffects": false | ||
} |
Oops, something went wrong.