Skip to content

Commit 5a692c7

Browse files
committed
build(cdn): Ensure we properly polyfill ES5 methods
1 parent 4e010db commit 5a692c7

File tree

11 files changed

+104
-19
lines changed

11 files changed

+104
-19
lines changed

packages/eslint-config-sdk/src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ module.exports = {
161161

162162
// All imports should be accounted for
163163
'import/no-extraneous-dependencies': 'error',
164+
165+
// Do not allow usage of functions we do not polyfill for ES5
166+
'@sentry-internal/sdk/no-unsupported-es6-methods': 'error',
164167
},
165168
},
166169
{

packages/eslint-plugin-sdk/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ module.exports = {
1313
'no-optional-chaining': require('./rules/no-optional-chaining'),
1414
'no-nullish-coalescing': require('./rules/no-nullish-coalescing'),
1515
'no-eq-empty': require('./rules/no-eq-empty'),
16+
'no-unsupported-es6-methods': require('./rules/no-unsupported-es6-methods'),
1617
},
1718
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
/**
4+
* Taken and adapted from https://github.com/nkt/eslint-plugin-es5/blob/master/src/rules/no-es6-methods.js
5+
*/
6+
7+
module.exports = {
8+
meta: {
9+
docs: {
10+
description: 'Forbid methods added in ES6 which are not polyfilled by Sentry.',
11+
},
12+
schema: [],
13+
},
14+
create(context) {
15+
return {
16+
CallExpression(node) {
17+
if (!node.callee || !node.callee.property) {
18+
return;
19+
}
20+
const functionName = node.callee.property.name;
21+
22+
const es6ArrayFunctions = ['copyWithin', 'values', 'fill'];
23+
const es6StringFunctions = ['repeat'];
24+
25+
const es6Functions = [].concat(es6ArrayFunctions, es6StringFunctions);
26+
if (es6Functions.indexOf(functionName) > -1) {
27+
context.report({
28+
node: node.callee.property,
29+
message: `ES6 methods not allowed: ${functionName}`,
30+
});
31+
}
32+
},
33+
};
34+
},
35+
};

packages/node/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ module.exports = {
66
rules: {
77
'@sentry-internal/sdk/no-optional-chaining': 'off',
88
'@sentry-internal/sdk/no-nullish-coalescing': 'off',
9+
'@sentry-internal/sdk/no-unsupported-es6-methods': 'off',
910
},
1011
};

packages/overhead-metrics/.eslintrc.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = {
1010
'import/no-unresolved': 'off',
1111
'@sentry-internal/sdk/no-optional-chaining': 'off',
1212
'@sentry-internal/sdk/no-nullish-coalescing': 'off',
13+
'@sentry-internal/sdk/no-unsupported-es6-methods': 'off',
1314
'jsdoc/require-jsdoc': 'off',
1415
},
1516
},

packages/replay/.eslintrc.js

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,8 @@ module.exports = {
77
extends: ['../../.eslintrc.js'],
88
overrides: [
99
{
10-
files: ['worker/**/*.ts'],
11-
parserOptions: {
12-
// TODO: figure out if we need a worker-specific tsconfig
13-
project: ['tsconfig.worker.json'],
14-
},
15-
rules: {
16-
// We cannot use backticks, as that conflicts with the stringified worker
17-
'prefer-template': 'off',
18-
},
19-
},
20-
{
21-
files: ['src/worker/**/*.js'],
22-
parserOptions: {
23-
sourceType: 'module',
24-
},
10+
files: ['src/**/*.ts'],
11+
rules: {},
2512
},
2613
{
2714
files: ['jest.setup.ts', 'jest.config.ts'],

packages/svelte/.eslintrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@ module.exports = {
33
browser: true,
44
},
55
extends: ['../../.eslintrc.js'],
6+
rules: {
7+
'@sentry-internal/sdk/no-unsupported-es6-methods': 'off',
8+
},
69
};

packages/vue/src/components.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const ANONYMOUS_COMPONENT_NAME = '<Anonymous>';
99

1010
const repeat = (str: string, n: number): string => {
1111
// string.repeat() is not supported by IE11, we fall back to just using the string in that case
12+
// eslint-disable-next-line @sentry-internal/sdk/no-unsupported-es6-methods
1213
return str.repeat ? str.repeat(n) : str;
1314
};
1415

rollup/bundleHelpers.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
makeTerserPlugin,
1818
makeTSPlugin,
1919
makeSetSDKSourcePlugin,
20+
getEs5Polyfills,
2021
} from './plugins/index.js';
2122
import { mergePlugins } from './utils';
2223

@@ -25,6 +26,8 @@ const BUNDLE_VARIANTS = ['.js', '.min.js', '.debug.min.js'];
2526
export function makeBaseBundleConfig(options) {
2627
const { bundleType, entrypoints, jsVersion, licenseTitle, outputFileBase, packageSpecificConfig } = options;
2728

29+
const isEs5 = jsVersion.toLowerCase() === 'es5';
30+
2831
const nodeResolvePlugin = makeNodeResolvePlugin();
2932
const sucrasePlugin = makeSucrasePlugin();
3033
const cleanupPlugin = makeCleanupPlugin();
@@ -42,6 +45,10 @@ export function makeBaseBundleConfig(options) {
4245
output: {
4346
format: 'iife',
4447
name: 'Sentry',
48+
outro: () => {
49+
// Add polyfills for ES6 array/string methods at the end of the bundle
50+
return isEs5 ? getEs5Polyfills() : '';
51+
},
4552
},
4653
context: 'window',
4754
plugins: [markAsBrowserBuildPlugin],
@@ -101,10 +108,9 @@ export function makeBaseBundleConfig(options) {
101108
strict: false,
102109
esModule: false,
103110
},
104-
plugins:
105-
jsVersion === 'es5'
106-
? [tsPlugin, nodeResolvePlugin, cleanupPlugin, licensePlugin]
107-
: [sucrasePlugin, nodeResolvePlugin, cleanupPlugin, licensePlugin],
111+
plugins: isEs5
112+
? [tsPlugin, nodeResolvePlugin, cleanupPlugin, licensePlugin]
113+
: [sucrasePlugin, nodeResolvePlugin, cleanupPlugin, licensePlugin],
108114
treeshake: 'smallest',
109115
};
110116

rollup/plugins/bundlePlugins.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
* Typescript plugin docs: https://github.com/ezolenko/rollup-plugin-typescript2
99
*/
1010

11+
import * as fs from 'fs';
12+
import * as path from 'path';
13+
1114
import commonjs from '@rollup/plugin-commonjs';
1215
import deepMerge from 'deepmerge';
1316
import license from 'rollup-plugin-license';
@@ -38,6 +41,11 @@ export function makeLicensePlugin(title) {
3841
return plugin;
3942
}
4043

44+
export function getEs5Polyfills() {
45+
// Note: __dirname resolves to e.g. packages/browser or packages/tracing
46+
return fs.readFileSync(path.join(__dirname, '../../rollup/polyfills/es5.js'), 'utf-8');
47+
}
48+
4149
/**
4250
* Create a plugin to set the value of the `__SENTRY_DEBUG__` magic string.
4351
*

rollup/polyfills/es5.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Sentry ES5 polyfills
2+
if (!('includes' in Array.prototype)) {
3+
Array.prototype.includes = function (searchElement) {
4+
return this.indexOf(searchElement) > -1;
5+
};
6+
}
7+
if (!('find' in Array.prototype)) {
8+
Array.prototype.find = function (callback) {
9+
for (var i = 0; i < this.length; i++) {
10+
if (callback(this[i])) {
11+
return this[i];
12+
}
13+
}
14+
};
15+
}
16+
if (!('findIndex' in Array.prototype)) {
17+
Array.prototype.findIndex = function (callback) {
18+
for (var i = 0; i < this.length; i++) {
19+
if (callback(this[i])) {
20+
return i;
21+
}
22+
}
23+
};
24+
}
25+
if (!('includes' in String.prototype)) {
26+
String.prototype.includes = function (searchElement) {
27+
return this.indexOf(searchElement) > -1;
28+
};
29+
}
30+
if (!('startsWith' in String.prototype)) {
31+
String.prototype.startsWith = function (searchElement) {
32+
return this.indexOf(searchElement) === 0;
33+
};
34+
}
35+
if (!('endsWith' in String.prototype)) {
36+
String.prototype.endsWith = function (searchElement) {
37+
return this.indexOf(searchElement) === this.length - searchElement.length;
38+
};
39+
}

0 commit comments

Comments
 (0)