Skip to content

Commit a8b2bea

Browse files
committed
refactor web-worker package
1 parent 324d5f8 commit a8b2bea

18 files changed

+267
-221
lines changed

dockerfiles/Dockerfile.node

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,33 @@
11
# CI test image for unit/lint/type tests
2-
FROM node:18-alpine@sha256:974afb6cbc0314dc6502b14243b8a39fbb2d04d975e9059dd066be3e274fbb25 as node-feature-builder
2+
FROM node:18-alpine@sha256:974afb6cbc0314dc6502b14243b8a39fbb2d04d975e9059dd066be3e274fbb25 AS node-feature-builder
33

44
RUN apk add --update bash python3 make gcc g++ musl-dev xvfb-run curl
55

66
WORKDIR /app
77

88
COPY package*.json ./
9-
COPY babel.config.js lerna.json .eslintignore .eslintrc.js jest.config.js tsconfig.json ./
9+
COPY babel.config.js lerna.json eslint.config.mjs jest.config.js tsconfig.json ./
1010
COPY jest ./jest
1111
ADD min_packages.tar .
12+
COPY .rollup ./.rollup
1213
COPY bin ./bin
1314
COPY packages ./packages
1415

1516
RUN npm ci
17+
1618
RUN npm run build
1719

20+
RUN npm pack --verbose packages/core/
1821
RUN npm pack --verbose packages/node/
22+
RUN npm pack --verbose packages/path-normalizer/
1923
RUN npm pack --verbose packages/plugin-express/
2024
RUN npm pack --verbose packages/plugin-koa/
2125
RUN npm pack --verbose packages/plugin-restify/
2226
RUN npm pack --verbose packages/plugin-hono/
2327

2428
# The maze-runner node tests
25-
FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v9-cli as node-maze-runner
29+
FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v9-cli AS node-maze-runner
2630
WORKDIR /app/
27-
COPY packages/node/ .
2831
COPY test/node/features test/node/features
2932
COPY --from=node-feature-builder /app/*.tgz ./
3033
RUN for d in test/node/features/fixtures/*/; do cp /app/*.tgz "$d"; done
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const babelConfig = require('../../babel.config.js')
2+
3+
module.exports = babelConfig

packages/web-worker/esm.config.js

Lines changed: 0 additions & 34 deletions
This file was deleted.

packages/web-worker/package.json

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@
33
"version": "8.4.0",
44
"description": "BugSnag error reporter for JavaScript web workers and service workers",
55
"homepage": "https://www.bugsnag.com/",
6-
"main": "dist/bugsnag.web-worker.js",
7-
"module": "dist/bugsnag.web-worker.js",
8-
"types": "types/notifier.ts",
6+
"main": "dist/index.js",
7+
"module": "dist/index.js",
8+
"types": "dist/types/index.d.ts",
9+
"exports": {
10+
".": {
11+
"types": "./dist/types/index.d.ts",
12+
"import": "./dist/index.js",
13+
"default": "./dist/index.js"
14+
}
15+
},
916
"repository": {
1017
"type": "git",
1118
"url": "git@github.com:bugsnag/bugsnag-js.git"
@@ -14,8 +21,7 @@
1421
"access": "public"
1522
},
1623
"files": [
17-
"dist",
18-
"types"
24+
"dist"
1925
],
2026
"keywords": [
2127
"worker",
@@ -28,11 +34,8 @@
2834
],
2935
"scripts": {
3036
"clean": "rm -fr dist && mkdir dist",
31-
"build": "npm run clean && npm run build:dist && npm run build:dist:min",
32-
"build:dist": "webpack",
33-
"build:dist:min": "webpack --optimization-minimize --output-filename=bugsnag.web-worker.min.js",
34-
"build:dist:esm": "webpack --config esm.config.js",
35-
"build:dist:esm.min": "webpack --config esm.config.js --optimization-minimize --output-filename=bugsnag.web-worker.min.mjs",
37+
"build": "npm run clean && npm run build:npm",
38+
"build:npm": "rollup --config rollup.config.npm.mjs",
3639
"size": "../../bin/size dist/bugsnag.web-worker.min.js",
3740
"cdn-upload": "../../bin/cdn-upload dist/*"
3841
},
@@ -46,9 +49,18 @@
4649
"@bugsnag/plugin-client-ip": "^8.4.0",
4750
"@bugsnag/plugin-window-onerror": "^8.4.0",
4851
"@bugsnag/plugin-window-unhandled-rejection": "^8.4.0",
52+
"@rollup/plugin-babel": "^6.0.4",
53+
"@rollup/plugin-commonjs": "^28.0.2",
54+
"@rollup/plugin-node-resolve": "^16.0.0",
55+
"@rollup/plugin-replace": "^6.0.2",
56+
"@rollup/plugin-terser": "^0.4.4",
57+
"rollup": "^4.31.0",
4958
"ts-loader": "^9.4.1",
5059
"typescript": "^4.9.3",
51-
"webpack": "^5.75.0",
52-
"webpack-cli": "^5.0.0"
60+
"webpack-cli": "^5.0.0",
61+
"webpack": "^5.75.0"
62+
},
63+
"dependencies": {
64+
"@bugsnag/core": "^8.1.1"
5365
}
5466
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import babel from '@rollup/plugin-babel'
2+
import commonjs from '@rollup/plugin-commonjs'
3+
import nodeResolve from '@rollup/plugin-node-resolve'
4+
import replace from '@rollup/plugin-replace'
5+
import terser from '@rollup/plugin-terser'
6+
import typescript from '@rollup/plugin-typescript'
7+
import fs from 'fs'
8+
9+
import createRollupConfig, { sharedOutput } from '../../.rollup/index.mjs'
10+
11+
const packageJson = JSON.parse(fs.readFileSync('./package.json'))
12+
13+
const plugins = [
14+
nodeResolve({
15+
browser: true
16+
}),
17+
commonjs(),
18+
typescript({
19+
removeComments: true,
20+
// don't output anything if there's a TS error
21+
noEmitOnError: true,
22+
compilerOptions: {
23+
target: 'es2015'
24+
}
25+
}),
26+
babel({ babelHelpers: 'bundled' }),
27+
replace({
28+
preventAssignment: true,
29+
values: {
30+
'process.env.NODE_ENV': JSON.stringify('production'),
31+
__BUGSNAG_NOTIFIER_VERSION__: packageJson.version,
32+
}
33+
})
34+
]
35+
36+
export default [
37+
createRollupConfig({
38+
input: 'src/index.ts',
39+
output: [
40+
{
41+
...sharedOutput,
42+
preserveModules: false,
43+
entryFileNames: '[name].js',
44+
format: 'esm'
45+
}
46+
],
47+
plugins
48+
}),
49+
createRollupConfig({
50+
input: 'src/index-umd.ts',
51+
output: [
52+
{
53+
...sharedOutput,
54+
entryFileNames: 'bugsnag.web-worker.js',
55+
format: 'umd',
56+
name: 'Bugsnag'
57+
},
58+
{
59+
...sharedOutput,
60+
entryFileNames: 'bugsnag.web-worker.min.js',
61+
format: 'umd',
62+
compact: true,
63+
name: 'Bugsnag',
64+
plugins: [terser()]
65+
}
66+
],
67+
plugins
68+
})
69+
]

packages/web-worker/src/bugsnag.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* eslint-env worker, serviceworker */
2+
3+
import delivery from '@bugsnag/delivery-fetch'
4+
import pluginClientIp from '@bugsnag/plugin-client-ip'
5+
import pluginWindowOnError from '@bugsnag/plugin-window-onerror'
6+
import pluginWindowUnhandledRejection from '@bugsnag/plugin-window-unhandled-rejection'
7+
8+
// extend the base config schema with some browser-specific options
9+
import workerConfig from './config'
10+
import pluginBrowserDevice from '@bugsnag/plugin-browser-device'
11+
import pluginBrowserSession from '@bugsnag/plugin-browser-session'
12+
import pluginPreventDiscard from './prevent-discard'
13+
import { Client, Config, BugsnagStatic, schema as baseConfig } from '@bugsnag/core'
14+
15+
16+
export interface WorkerConfig extends Config {
17+
collectUserIp?: boolean
18+
generateAnonymousId?: boolean
19+
}
20+
21+
export interface WorkerBugsnagStatic extends BugsnagStatic {
22+
start(apiKeyOrOpts: string | WorkerConfig): Client
23+
createClient(apiKeyOrOpts: string | WorkerConfig): Client
24+
}
25+
26+
const name = 'Bugsnag Web Worker'
27+
const url = 'https://github.com/bugsnag/bugsnag-js'
28+
const version = '__BUGSNAG_NOTIFIER_VERSION__'
29+
30+
// extend the base config schema with some worker-specific options
31+
const schema = Object.assign({}, baseConfig, workerConfig)
32+
33+
type WorkerClient = Partial<Client> & {
34+
_client: Client | null
35+
createClient: (opts?: Config) => Client
36+
start: (opts?: Config) => Client
37+
isStarted: () => boolean
38+
}
39+
40+
const notifier: WorkerClient = {
41+
_client: null,
42+
// @ts-expect-error
43+
createClient: (opts) => {
44+
// handle very simple use case where user supplies just the api key as a string
45+
if (typeof opts === 'string') opts = { apiKey: opts }
46+
if (!opts) opts = {} as unknown as Config
47+
48+
const internalPlugins = [
49+
pluginBrowserDevice(navigator, null),
50+
pluginBrowserSession,
51+
pluginClientIp,
52+
pluginPreventDiscard,
53+
pluginWindowOnError(self, 'worker onerror'),
54+
pluginWindowUnhandledRejection(self)
55+
]
56+
57+
// configure a client with user supplied options
58+
const bugsnag = new Client(opts, schema, internalPlugins, { name, version, url })
59+
60+
bugsnag._setDelivery(client => delivery(client, self.fetch, self))
61+
62+
bugsnag._logger.debug('Loaded!')
63+
64+
return bugsnag._config.autoTrackSessions
65+
? bugsnag.startSession()
66+
: bugsnag
67+
},
68+
start: (opts) => {
69+
if (notifier._client) {
70+
notifier._client._logger.warn('Bugsnag.start() was called more than once. Ignoring.')
71+
return notifier._client
72+
}
73+
notifier._client = notifier.createClient(opts)
74+
return notifier._client
75+
},
76+
isStarted: () => {
77+
return notifier._client != null
78+
}
79+
}
80+
81+
;
82+
// Add client functions to notifier
83+
(Object.getOwnPropertyNames(Client.prototype)).forEach(method => {
84+
// skip private methods
85+
if (/^_/.test(method) || method === 'constructor') return
86+
// @ts-expect-error
87+
notifier[method] = function () {
88+
if (!notifier._client) return console.log(`Bugsnag.${method}() was called before Bugsnag.start()`)
89+
notifier._client._depth += 1
90+
// @ts-expect-error
91+
const ret = notifier._client[method].apply(notifier._client, arguments)
92+
notifier._client._depth -= 1
93+
return ret
94+
}
95+
})
96+
97+
// @ts-expect-error
98+
const Bugsnag = notifier as WorkerBugsnagStatic
99+
100+
export default Bugsnag

packages/web-worker/src/config.js

Lines changed: 0 additions & 38 deletions
This file was deleted.

packages/web-worker/src/config.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* eslint-env worker, serviceworker */
2+
3+
import { schema } from '@bugsnag/core'
4+
5+
import getPrefixedConsole from './get-prefixed-console'
6+
7+
export default {
8+
appType: {
9+
...schema.appType,
10+
defaultValue: () => 'workerjs'
11+
},
12+
logger: Object.assign({}, schema.logger, {
13+
defaultValue: () =>
14+
(typeof console !== 'undefined' && typeof console.debug === 'function')
15+
? getPrefixedConsole()
16+
: undefined
17+
}),
18+
autoTrackSessions: {
19+
...schema.autoTrackSessions,
20+
defaultValue: () => false
21+
},
22+
autoDetectErrors: {
23+
...schema.autoTrackSessions,
24+
defaultValue: () => false
25+
}
26+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type LoggerMethod = 'debug' | 'info' | 'warn' | 'error'
2+
3+
const getPrefixedConsole = () => {
4+
const logger: Record<string, unknown> = {}
5+
const consoleLog = console.log
6+
const loggerMethods = ['debug', 'info', 'warn', 'error'] as const
7+
loggerMethods.map((method: LoggerMethod) => {
8+
const consoleMethod = console[method]
9+
logger[method] = typeof consoleMethod === 'function'
10+
? consoleMethod.bind(console, '[bugsnag]')
11+
: consoleLog.bind(console, '[bugsnag]')
12+
})
13+
return logger
14+
}
15+
16+
export default getPrefixedConsole

0 commit comments

Comments
 (0)