diff --git a/packages/eslint-config-sdk/src/index.js b/packages/eslint-config-sdk/src/index.js index b93cc63508df..d09be9e2e67d 100644 --- a/packages/eslint-config-sdk/src/index.js +++ b/packages/eslint-config-sdk/src/index.js @@ -143,7 +143,10 @@ module.exports = { }, ], + // We want to prevent optional chaining & nullish coalescing usage in our files + // to prevent uncessary bundle size. Turned off in tests. '@sentry-internal/sdk/no-optional-chaining': 'error', + '@sentry-internal/sdk/no-nullish-coalescing': 'error', // JSDOC comments are required for classes and methods. As we have a public facing codebase, documentation, // even if it may seems excessive at times, is important to emphasize. Turned off in tests. @@ -177,6 +180,7 @@ module.exports = { '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-empty-function': 'off', '@sentry-internal/sdk/no-optional-chaining': 'off', + '@sentry-internal/sdk/no-nullish-coalescing': 'off', }, }, { diff --git a/packages/eslint-plugin-sdk/src/index.js b/packages/eslint-plugin-sdk/src/index.js index 8b94bbe4705b..31ac785abf5e 100644 --- a/packages/eslint-plugin-sdk/src/index.js +++ b/packages/eslint-plugin-sdk/src/index.js @@ -11,6 +11,7 @@ module.exports = { rules: { 'no-optional-chaining': require('./rules/no-optional-chaining'), + 'no-nullish-coalescing': require('./rules/no-nullish-coalescing'), 'no-eq-empty': require('./rules/no-eq-empty'), }, }; diff --git a/packages/eslint-plugin-sdk/src/rules/no-nullish-coalescing.js b/packages/eslint-plugin-sdk/src/rules/no-nullish-coalescing.js new file mode 100644 index 000000000000..8944f2755632 --- /dev/null +++ b/packages/eslint-plugin-sdk/src/rules/no-nullish-coalescing.js @@ -0,0 +1,48 @@ +/** + * @fileoverview disallow nullish coalescing operators as they were introduced only in ES2020 and hence require + * us to add a polyfill. This increases bundle size more than avoiding nullish coalescing operators all together. + * + * @author Lukas Stracke + * + * Based on: https://github.com/mysticatea/eslint-plugin-es/blob/v4.1.0/lib/rules/no-nullish-coalescing-operators.js + */ +'use strict'; + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'disallow nullish coalescing operators.', + category: 'Best Practices', + recommended: true, + }, + messages: { + forbidden: 'Avoid using nullish coalescing operators.', + }, + fixable: null, + schema: [], + }, + create(context) { + return { + "LogicalExpression[operator='??']"(node) { + context.report({ + node: context.getSourceCode().getTokenAfter(node.left, isNullishCoalescingOperator), + messageId: 'forbidden', + }); + }, + }; + }, +}; + +/** + * Checks if the given token is a nullish coalescing operator or not. + * @param {Token} token - The token to check. + * @returns {boolean} `true` if the token is a nullish coalescing operator. + */ +function isNullishCoalescingOperator(token) { + return token.value === '??' && token.type === 'Punctuator'; +} diff --git a/packages/nextjs/.eslintrc.js b/packages/nextjs/.eslintrc.js index b6f6b1b9938c..96c2b0d8e4a2 100644 --- a/packages/nextjs/.eslintrc.js +++ b/packages/nextjs/.eslintrc.js @@ -10,6 +10,7 @@ module.exports = { extends: ['../../.eslintrc.js'], rules: { '@sentry-internal/sdk/no-optional-chaining': 'off', + '@sentry-internal/sdk/no-nullish-coalescing': 'off', }, overrides: [ { diff --git a/packages/node/.eslintrc.js b/packages/node/.eslintrc.js index 9899ea1b73d8..e15b119aa31e 100644 --- a/packages/node/.eslintrc.js +++ b/packages/node/.eslintrc.js @@ -5,5 +5,6 @@ module.exports = { extends: ['../../.eslintrc.js'], rules: { '@sentry-internal/sdk/no-optional-chaining': 'off', + '@sentry-internal/sdk/no-nullish-coalescing': 'off', }, }; diff --git a/packages/tracing/src/browser/browsertracing.ts b/packages/tracing/src/browser/browsertracing.ts index 5fb1a81f0779..8502e5d1b13f 100644 --- a/packages/tracing/src/browser/browsertracing.ts +++ b/packages/tracing/src/browser/browsertracing.ts @@ -317,7 +317,7 @@ export class BrowserTracing implements Integration { op, trimEnd: true, metadata: { - source: this._latestRouteSource ?? 'url', + source: this._latestRouteSource || 'url', }, }; diff --git a/packages/tracing/src/browser/metrics/index.ts b/packages/tracing/src/browser/metrics/index.ts index 7bd575e90024..67cdc1714ed9 100644 --- a/packages/tracing/src/browser/metrics/index.ts +++ b/packages/tracing/src/browser/metrics/index.ts @@ -304,7 +304,7 @@ function _addPerformanceNavigationTiming( } _startChild(transaction, { op: 'browser', - description: description ?? event, + description: description || event, startTimestamp: timeOrigin + msToSec(start), endTimestamp: timeOrigin + msToSec(end), }); diff --git a/packages/tracing/src/span.ts b/packages/tracing/src/span.ts index db11bb931df7..72f27721bb28 100644 --- a/packages/tracing/src/span.ts +++ b/packages/tracing/src/span.ts @@ -294,17 +294,17 @@ export class Span implements SpanInterface { * @inheritDoc */ public updateWithContext(spanContext: SpanContext): this { - this.data = spanContext.data ?? {}; + this.data = spanContext.data || {}; this.description = spanContext.description; this.endTimestamp = spanContext.endTimestamp; this.op = spanContext.op; this.parentSpanId = spanContext.parentSpanId; this.sampled = spanContext.sampled; - this.spanId = spanContext.spanId ?? this.spanId; - this.startTimestamp = spanContext.startTimestamp ?? this.startTimestamp; + this.spanId = spanContext.spanId || this.spanId; + this.startTimestamp = spanContext.startTimestamp || this.startTimestamp; this.status = spanContext.status; - this.tags = spanContext.tags ?? {}; - this.traceId = spanContext.traceId ?? this.traceId; + this.tags = spanContext.tags || {}; + this.traceId = spanContext.traceId || this.traceId; return this; } diff --git a/packages/tracing/src/transaction.ts b/packages/tracing/src/transaction.ts index b93d52b81c38..5b32612302ee 100644 --- a/packages/tracing/src/transaction.ts +++ b/packages/tracing/src/transaction.ts @@ -238,7 +238,7 @@ export class Transaction extends SpanClass implements TransactionInterface { public updateWithContext(transactionContext: TransactionContext): this { super.updateWithContext(transactionContext); - this.name = transactionContext.name ?? ''; + this.name = transactionContext.name || ''; this._trimEnd = transactionContext.trimEnd;