From 57f837b48dd1110db99056de8b223fa6aa4220c3 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 28 Mar 2024 14:26:59 +0000 Subject: [PATCH 1/8] feat: Add loader file to node-based SDKs to support ESM --- dev-packages/rollup-utils/.eslintrc.cjs | 5 ++ .../rollup-utils/code/otelLoaderTemplate.js | 1 + dev-packages/rollup-utils/npmHelpers.mjs | 40 ++++++++++++++ nx.json | 2 +- packages/astro/package.json | 11 +++- packages/astro/rollup.npm.config.mjs | 4 +- packages/aws-serverless/package.json | 11 +++- packages/aws-serverless/rollup.npm.config.mjs | 27 +++++----- packages/google-cloud-serverless/package.json | 11 +++- .../rollup.npm.config.mjs | 4 +- packages/nextjs/package.json | 6 +++ packages/nextjs/rollup.npm.config.mjs | 3 +- packages/node/package.json | 11 +++- packages/node/rollup.npm.config.mjs | 3 +- packages/remix/package.json | 9 +++- packages/remix/rollup.npm.config.mjs | 27 +++++----- yarn.lock | 53 ++++++++++++++++--- 17 files changed, 181 insertions(+), 47 deletions(-) create mode 100644 dev-packages/rollup-utils/.eslintrc.cjs create mode 100644 dev-packages/rollup-utils/code/otelLoaderTemplate.js diff --git a/dev-packages/rollup-utils/.eslintrc.cjs b/dev-packages/rollup-utils/.eslintrc.cjs new file mode 100644 index 000000000000..0939c10d3812 --- /dev/null +++ b/dev-packages/rollup-utils/.eslintrc.cjs @@ -0,0 +1,5 @@ +module.exports = { + extends: ['../../.eslintrc.js'], + ignorePatterns: ['otelLoaderTemplate.js.tmpl'], + sourceType: 'module', +}; diff --git a/dev-packages/rollup-utils/code/otelLoaderTemplate.js b/dev-packages/rollup-utils/code/otelLoaderTemplate.js new file mode 100644 index 000000000000..b364ef0082c9 --- /dev/null +++ b/dev-packages/rollup-utils/code/otelLoaderTemplate.js @@ -0,0 +1 @@ +export * from 'import-in-the-middle/hook.mjs'; diff --git a/dev-packages/rollup-utils/npmHelpers.mjs b/dev-packages/rollup-utils/npmHelpers.mjs index 86941fc8db29..b08dd8a3b908 100644 --- a/dev-packages/rollup-utils/npmHelpers.mjs +++ b/dev-packages/rollup-utils/npmHelpers.mjs @@ -5,9 +5,11 @@ import * as fs from 'fs'; import { builtinModules } from 'module'; import * as path from 'path'; +import { fileURLToPath } from 'url'; import deepMerge from 'deepmerge'; +import { defineConfig } from 'rollup'; import { makeCleanupPlugin, makeCodeCovPlugin, @@ -21,6 +23,8 @@ import { import { makePackageNodeEsm } from './plugins/make-esm-plugin.mjs'; import { mergePlugins } from './utils.mjs'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const packageDotJSON = JSON.parse(fs.readFileSync(path.resolve(process.cwd(), './package.json'), { encoding: 'utf8' })); export function makeBaseNPMConfig(options = {}) { @@ -141,3 +145,39 @@ export function makeNPMConfigVariants(baseConfig, options = {}) { return variantSpecificConfigs.map(variant => deepMerge(baseConfig, variant)); } + +/** + * This creates a loader file at the target location as part of the rollup build. + * This loader script can then be used in combination with various Node.js flags (like --loader=...) to monkeypatch 3rd party modules. + */ +export function makeOtelLoader(outputPath) { + const foundLoaderExport = Object.keys(packageDotJSON.exports ?? {}).some(key => { + return packageDotJSON?.exports?.[key]?.import?.default === outputPath; + }); + if (!foundLoaderExport) { + throw new Error( + `You used the makeOtelLoader() rollup utility without specifying the loader inside \`exports[something].import.default\`. Please add "${outputPath}" as a value there (maybe check for typos - it needs to be "${outputPath}" exactly).`, + ); + } + + const foundImportInTheMiddleDep = Object.keys(packageDotJSON.dependencies ?? {}).some(key => { + return key === 'import-in-the-middle' && packageDotJSON?.dependencies?.[key] === '1.7.1'; + }); + if (!foundImportInTheMiddleDep) { + throw new Error( + `You used the makeOtelLoader() rollup utility but didn't specify the "import-in-the-middle": "1.7.1" dependency in ${path.resolve( + process.cwd(), + 'package.json', + )}. Please add it to the dependencies.`, + ); + } + + return defineConfig({ + input: path.join(__dirname, 'code', 'otelLoaderTemplate.js'), + external: ['import-in-the-middle/hook.mjs'], + output: { + format: 'esm', + file: outputPath, + }, + }); +} diff --git a/nx.json b/nx.json index 1fe8820b9110..6e87a77ccbbe 100644 --- a/nx.json +++ b/nx.json @@ -10,7 +10,7 @@ }, "namedInputs": { "default": ["{projectRoot}/**/*", "sharedGlobals"], - "sharedGlobals": ["{workspaceRoot}/*.js", "{workspaceRoot}/*.json", "{workspaceRoot}/yarn.lock"], + "sharedGlobals": ["{workspaceRoot}/*.js", "{workspaceRoot}/*.json", "{workspaceRoot}/yarn.lock", "{workspaceRoot}/dev-packages/rollup-utils/**"], "production": ["default", "!{projectRoot}/test/**/*", "!{projectRoot}/**/*.md", "!{projectRoot}/*.tgz"] }, "targetDefaults": { diff --git a/packages/astro/package.json b/packages/astro/package.json index 7a08d5fbabf5..55699454253d 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -21,7 +21,8 @@ "cjs", "esm", "types", - "types-ts3.8" + "types-ts3.8", + "register.mjs" ], "main": "build/cjs/index.client.js", "module": "build/esm/index.server.js", @@ -40,6 +41,11 @@ "import": "./build/esm/integration/middleware/index.js", "require": "./build/cjs/integration/middleware/index.js", "types": "./build/types/integration/middleware/index.types.d.ts" + }, + "./register": { + "import": { + "default": "./build/register.mjs" + } } }, "publishConfig": { @@ -54,7 +60,8 @@ "@sentry/node": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", - "@sentry/vite-plugin": "^2.14.2" + "@sentry/vite-plugin": "^2.14.2", + "import-in-the-middle": "1.7.1" }, "devDependencies": { "astro": "^3.5.0", diff --git a/packages/astro/rollup.npm.config.mjs b/packages/astro/rollup.npm.config.mjs index c485392d0ec7..92762b2b499c 100644 --- a/packages/astro/rollup.npm.config.mjs +++ b/packages/astro/rollup.npm.config.mjs @@ -1,4 +1,4 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; const variants = makeNPMConfigVariants( makeBaseNPMConfig({ @@ -14,4 +14,4 @@ const variants = makeNPMConfigVariants( }), ); -export default variants; +export default [...variants, makeOtelLoader('./build/register.mjs')]; diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index f341f28809f1..37dd5912227a 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -12,7 +12,8 @@ "files": [ "cjs", "types", - "types-ts3.8" + "types-ts3.8", + "register.mjs" ], "main": "build/npm/cjs/index.js", "types": "build/npm/types/index.d.ts", @@ -23,6 +24,11 @@ "types": "./build/npm/types/index.d.ts", "default": "./build/npm/cjs/index.js" } + }, + "./register": { + "import": { + "default": "./build/register.mjs" + } } }, "typesVersions": { @@ -41,7 +47,8 @@ "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", "@types/aws-lambda": "^8.10.62", - "@types/express": "^4.17.14" + "@types/express": "^4.17.14", + "import-in-the-middle": "1.7.1" }, "devDependencies": { "@types/node": "^14.18.0", diff --git a/packages/aws-serverless/rollup.npm.config.mjs b/packages/aws-serverless/rollup.npm.config.mjs index ff28359cfeed..d99f7ded86e8 100644 --- a/packages/aws-serverless/rollup.npm.config.mjs +++ b/packages/aws-serverless/rollup.npm.config.mjs @@ -1,13 +1,16 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; -export default makeNPMConfigVariants( - makeBaseNPMConfig({ - // TODO: `awslambda-auto.ts` is a file which the lambda layer uses to automatically init the SDK. Does it need to be - // in the npm package? Is it possible that some people are using it themselves in the same way the layer uses it (in - // which case removing it would be a breaking change)? Should it stay here or not? - entrypoints: ['src/index.ts', 'src/awslambda-auto.ts'], - // packages with bundles have a different build directory structure - hasBundles: true, - }), - { emitEsm: false }, -); +export default [ + ...makeNPMConfigVariants( + makeBaseNPMConfig({ + // TODO: `awslambda-auto.ts` is a file which the lambda layer uses to automatically init the SDK. Does it need to be + // in the npm package? Is it possible that some people are using it themselves in the same way the layer uses it (in + // which case removing it would be a breaking change)? Should it stay here or not? + entrypoints: ['src/index.ts', 'src/awslambda-auto.ts'], + // packages with bundles have a different build directory structure + hasBundles: true, + }), + { emitEsm: false }, + ), + makeOtelLoader('./build/register.mjs'), +]; diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json index f602834a2341..49d426ed5be0 100644 --- a/packages/google-cloud-serverless/package.json +++ b/packages/google-cloud-serverless/package.json @@ -13,7 +13,8 @@ "cjs", "esm", "types", - "types-ts3.8" + "types-ts3.8", + "register.mjs" ], "main": "build/cjs/index.js", "types": "build/types/index.d.ts", @@ -24,6 +25,11 @@ "types": "./build/types/index.d.ts", "default": "./build/cjs/index.js" } + }, + "./register": { + "import": { + "default": "./build/register.mjs" + } } }, "typesVersions": { @@ -41,7 +47,8 @@ "@sentry/node": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", - "@types/express": "^4.17.14" + "@types/express": "^4.17.14", + "import-in-the-middle": "1.7.1" }, "devDependencies": { "@google-cloud/bigquery": "^5.3.0", diff --git a/packages/google-cloud-serverless/rollup.npm.config.mjs b/packages/google-cloud-serverless/rollup.npm.config.mjs index 84a06f2fb64a..2d6da37d7610 100644 --- a/packages/google-cloud-serverless/rollup.npm.config.mjs +++ b/packages/google-cloud-serverless/rollup.npm.config.mjs @@ -1,3 +1,3 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; -export default makeNPMConfigVariants(makeBaseNPMConfig()); +export default [...makeNPMConfigVariants(makeBaseNPMConfig()), makeOtelLoader('./build/register.mjs')]; diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 213958d1fd84..d56947dafda1 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -22,6 +22,11 @@ }, "node": "./build/cjs/index.server.js", "types": "./build/types/index.types.d.ts" + }, + "./register": { + "import": { + "default": "./build/register.mjs" + } } }, "typesVersions": { @@ -44,6 +49,7 @@ "@sentry/vercel-edge": "8.0.0-alpha.7", "@sentry/webpack-plugin": "2.16.0", "chalk": "3.0.0", + "import-in-the-middle": "1.7.1", "resolve": "1.22.8", "rollup": "3.29.4", "stacktrace-parser": "^0.1.10" diff --git a/packages/nextjs/rollup.npm.config.mjs b/packages/nextjs/rollup.npm.config.mjs index 39b79c9593b2..8fc31d35d64f 100644 --- a/packages/nextjs/rollup.npm.config.mjs +++ b/packages/nextjs/rollup.npm.config.mjs @@ -1,4 +1,4 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; export default [ ...makeNPMConfigVariants( @@ -72,4 +72,5 @@ export default [ }, }), ), + makeOtelLoader('./build/register.mjs'), ]; diff --git a/packages/node/package.json b/packages/node/package.json index 885ebe84f0b7..adc2ff570b49 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -13,7 +13,8 @@ "cjs", "esm", "types", - "types-ts3.8" + "types-ts3.8", + "register.mjs" ], "main": "build/cjs/index.js", "module": "build/esm/index.js", @@ -29,6 +30,11 @@ "types": "./build/types/index.d.ts", "default": "./build/cjs/index.js" } + }, + "./register": { + "import": { + "default": "./build/register.mjs" + } } }, "typesVersions": { @@ -65,7 +71,8 @@ "@sentry/core": "8.0.0-alpha.7", "@sentry/opentelemetry": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", - "@sentry/utils": "8.0.0-alpha.7" + "@sentry/utils": "8.0.0-alpha.7", + "import-in-the-middle": "1.7.1" }, "devDependencies": { "@types/node": "^14.18.0" diff --git a/packages/node/rollup.npm.config.mjs b/packages/node/rollup.npm.config.mjs index 17c0727d7eff..0568e8f32bb4 100644 --- a/packages/node/rollup.npm.config.mjs +++ b/packages/node/rollup.npm.config.mjs @@ -1,10 +1,11 @@ import replace from '@rollup/plugin-replace'; -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; import { createAnrWorkerCode } from './rollup.anr-worker.config.mjs'; const { workerRollupConfig, getBase64Code } = createAnrWorkerCode(); export default [ + makeOtelLoader('./build/register.mjs'), // The worker needs to be built first since it's output is used in the main bundle. workerRollupConfig, ...makeNPMConfigVariants( diff --git a/packages/remix/package.json b/packages/remix/package.json index a1684da9f0c4..848cb7d16104 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -17,7 +17,8 @@ "esm", "types", "types-ts3.8", - "scripts" + "scripts", + "register.mjs" ], "main": "build/cjs/index.server.js", "module": "build/esm/index.server.js", @@ -32,6 +33,11 @@ }, "node": "./build/cjs/index.server.js", "types": "./build/types/index.types.d.ts" + }, + "./register": { + "import": { + "default": "./build/register.mjs" + } } }, "typesVersions": { @@ -53,6 +59,7 @@ "@sentry/react": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", + "import-in-the-middle": "1.7.1", "glob": "^10.3.4", "yargs": "^17.6.0" }, diff --git a/packages/remix/rollup.npm.config.mjs b/packages/remix/rollup.npm.config.mjs index c588c260c703..4b2b0d1223f1 100644 --- a/packages/remix/rollup.npm.config.mjs +++ b/packages/remix/rollup.npm.config.mjs @@ -1,14 +1,17 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; -export default makeNPMConfigVariants( - makeBaseNPMConfig({ - entrypoints: ['src/index.server.ts', 'src/index.client.tsx'], - packageSpecificConfig: { - external: ['react-router', 'react-router-dom'], - output: { - // make it so Rollup calms down about the fact that we're combining default and named exports - exports: 'named', +export default [ + ...makeNPMConfigVariants( + makeBaseNPMConfig({ + entrypoints: ['src/index.server.ts', 'src/index.client.tsx'], + packageSpecificConfig: { + external: ['react-router', 'react-router-dom'], + output: { + // make it so Rollup calms down about the fact that we're combining default and named exports + exports: 'named', + }, }, - }, - }), -); + }), + ), + makeOtelLoader('./build/register.mjs'), +]; diff --git a/yarn.lock b/yarn.lock index 1c98b5a07dfd..4b8597372bb6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6756,8 +6756,17 @@ dependencies: "@types/unist" "*" -"@types/history-4@npm:@types/history@4.7.8", "@types/history-5@npm:@types/history@4.7.8", "@types/history@*": - name "@types/history-4" +"@types/history-4@npm:@types/history@4.7.8": + version "4.7.8" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" + integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== + +"@types/history-5@npm:@types/history@4.7.8": + version "4.7.8" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" + integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== + +"@types/history@*": version "4.7.8" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== @@ -7137,7 +7146,15 @@ "@types/history" "^3" "@types/react" "*" -"@types/react-router-4@npm:@types/react-router@5.1.14", "@types/react-router-5@npm:@types/react-router@5.1.14": +"@types/react-router-4@npm:@types/react-router@5.1.14": + version "5.1.14" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.14.tgz#e0442f4eb4c446541ad7435d44a97f8fe6df40da" + integrity sha512-LAJpqYUaCTMT2anZheoidiIymt8MuX286zoVFPM3DVb23aQBH0mAkFvzpd4LKqiolV8bBtZWT5Qp7hClCNDENw== + dependencies: + "@types/history" "*" + "@types/react" "*" + +"@types/react-router-5@npm:@types/react-router@5.1.14": version "5.1.14" resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.14.tgz#e0442f4eb4c446541ad7435d44a97f8fe6df40da" integrity sha512-LAJpqYUaCTMT2anZheoidiIymt8MuX286zoVFPM3DVb23aQBH0mAkFvzpd4LKqiolV8bBtZWT5Qp7hClCNDENw== @@ -25310,8 +25327,7 @@ react-is@^18.0.0: dependencies: "@remix-run/router" "1.0.2" -"react-router-6@npm:react-router@6.3.0", react-router@6.3.0: - name react-router-6 +"react-router-6@npm:react-router@6.3.0": version "6.3.0" resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== @@ -25326,6 +25342,13 @@ react-router-dom@^6.2.2: history "^5.2.0" react-router "6.3.0" +react-router@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" + integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== + dependencies: + history "^5.2.0" + react@^18.0.0: version "18.0.0" resolved "https://registry.yarnpkg.com/react/-/react-18.0.0.tgz#b468736d1f4a5891f38585ba8e8fb29f91c3cb96" @@ -27800,7 +27823,7 @@ stringify-object@^3.2.1: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -27828,6 +27851,13 @@ strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -30471,7 +30501,16 @@ workerpool@^6.4.0: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.4.0.tgz#f8d5cfb45fde32fa3b7af72ad617c3369567a462" integrity sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@7.0.0, wrap-ansi@^5.1.0, wrap-ansi@^6.2.0, wrap-ansi@^7.0.0, wrap-ansi@^8.1.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@7.0.0, wrap-ansi@^5.1.0, wrap-ansi@^6.2.0, wrap-ansi@^7.0.0, wrap-ansi@^8.1.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From a9fc29c4db3361beccc1736885c5aa3d456e2b10 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 28 Mar 2024 14:44:28 +0000 Subject: [PATCH 2/8] lint --- nx.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nx.json b/nx.json index 6e87a77ccbbe..d4a90a3a6777 100644 --- a/nx.json +++ b/nx.json @@ -10,7 +10,12 @@ }, "namedInputs": { "default": ["{projectRoot}/**/*", "sharedGlobals"], - "sharedGlobals": ["{workspaceRoot}/*.js", "{workspaceRoot}/*.json", "{workspaceRoot}/yarn.lock", "{workspaceRoot}/dev-packages/rollup-utils/**"], + "sharedGlobals": [ + "{workspaceRoot}/*.js", + "{workspaceRoot}/*.json", + "{workspaceRoot}/yarn.lock", + "{workspaceRoot}/dev-packages/rollup-utils/**" + ], "production": ["default", "!{projectRoot}/test/**/*", "!{projectRoot}/**/*.md", "!{projectRoot}/*.tgz"] }, "targetDefaults": { From 5a137d85f87bceaf3559acd2e85b8b33fded6962 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 28 Mar 2024 15:39:39 +0000 Subject: [PATCH 3/8] Add E2E test --- .../esm-loader-node-express-app/.npmrc | 2 + .../event-proxy-server.ts | 253 ++++++++++++++++++ .../esm-loader-node-express-app/package.json | 27 ++ .../playwright.config.ts | 68 +++++ .../esm-loader-node-express-app/src/app.mjs | 49 ++++ .../start-event-proxy.ts | 6 + .../tests/server.test.ts | 33 +++ 7 files changed, 438 insertions(+) create mode 100644 dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/.npmrc create mode 100644 dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/event-proxy-server.ts create mode 100644 dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json create mode 100644 dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/playwright.config.ts create mode 100644 dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/src/app.mjs create mode 100644 dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/start-event-proxy.ts create mode 100644 dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/.npmrc b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/.npmrc new file mode 100644 index 000000000000..070f80f05092 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/.npmrc @@ -0,0 +1,2 @@ +@sentry:registry=http://127.0.0.1:4873 +@sentry-internal:registry=http://127.0.0.1:4873 diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/event-proxy-server.ts b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/event-proxy-server.ts new file mode 100644 index 000000000000..d14ca5cb5e72 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/event-proxy-server.ts @@ -0,0 +1,253 @@ +import * as fs from 'fs'; +import * as http from 'http'; +import * as https from 'https'; +import type { AddressInfo } from 'net'; +import * as os from 'os'; +import * as path from 'path'; +import * as util from 'util'; +import * as zlib from 'zlib'; +import type { Envelope, EnvelopeItem, Event } from '@sentry/types'; +import { parseEnvelope } from '@sentry/utils'; + +const readFile = util.promisify(fs.readFile); +const writeFile = util.promisify(fs.writeFile); + +interface EventProxyServerOptions { + /** Port to start the event proxy server at. */ + port: number; + /** The name for the proxy server used for referencing it with listener functions */ + proxyServerName: string; +} + +interface SentryRequestCallbackData { + envelope: Envelope; + rawProxyRequestBody: string; + rawSentryResponseBody: string; + sentryResponseStatusCode?: number; +} + +/** + * Starts an event proxy server that will proxy events to sentry when the `tunnel` option is used. Point the `tunnel` + * option to this server (like this `tunnel: http://localhost:${port option}/`). + */ +export async function startEventProxyServer(options: EventProxyServerOptions): Promise { + const eventCallbackListeners: Set<(data: string) => void> = new Set(); + + const proxyServer = http.createServer((proxyRequest, proxyResponse) => { + const proxyRequestChunks: Uint8Array[] = []; + + proxyRequest.addListener('data', (chunk: Buffer) => { + proxyRequestChunks.push(chunk); + }); + + proxyRequest.addListener('error', err => { + throw err; + }); + + proxyRequest.addListener('end', () => { + const proxyRequestBody = + proxyRequest.headers['content-encoding'] === 'gzip' + ? zlib.gunzipSync(Buffer.concat(proxyRequestChunks)).toString() + : Buffer.concat(proxyRequestChunks).toString(); + + let envelopeHeader = JSON.parse(proxyRequestBody.split('\n')[0]); + + if (!envelopeHeader.dsn) { + throw new Error('[event-proxy-server] No dsn on envelope header. Please set tunnel option.'); + } + + const { origin, pathname, host } = new URL(envelopeHeader.dsn); + + const projectId = pathname.substring(1); + const sentryIngestUrl = `${origin}/api/${projectId}/envelope/`; + + proxyRequest.headers.host = host; + + const sentryResponseChunks: Uint8Array[] = []; + + const sentryRequest = https.request( + sentryIngestUrl, + { headers: proxyRequest.headers, method: proxyRequest.method }, + sentryResponse => { + sentryResponse.addListener('data', (chunk: Buffer) => { + proxyResponse.write(chunk, 'binary'); + sentryResponseChunks.push(chunk); + }); + + sentryResponse.addListener('end', () => { + eventCallbackListeners.forEach(listener => { + const rawSentryResponseBody = Buffer.concat(sentryResponseChunks).toString(); + + const data: SentryRequestCallbackData = { + envelope: parseEnvelope(proxyRequestBody), + rawProxyRequestBody: proxyRequestBody, + rawSentryResponseBody, + sentryResponseStatusCode: sentryResponse.statusCode, + }; + + listener(Buffer.from(JSON.stringify(data)).toString('base64')); + }); + proxyResponse.end(); + }); + + sentryResponse.addListener('error', err => { + throw err; + }); + + proxyResponse.writeHead(sentryResponse.statusCode || 500, sentryResponse.headers); + }, + ); + + sentryRequest.write(Buffer.concat(proxyRequestChunks), 'binary'); + sentryRequest.end(); + }); + }); + + const proxyServerStartupPromise = new Promise(resolve => { + proxyServer.listen(options.port, () => { + resolve(); + }); + }); + + const eventCallbackServer = http.createServer((eventCallbackRequest, eventCallbackResponse) => { + eventCallbackResponse.statusCode = 200; + eventCallbackResponse.setHeader('connection', 'keep-alive'); + + const callbackListener = (data: string): void => { + eventCallbackResponse.write(data.concat('\n'), 'utf8'); + }; + + eventCallbackListeners.add(callbackListener); + + eventCallbackRequest.on('close', () => { + eventCallbackListeners.delete(callbackListener); + }); + + eventCallbackRequest.on('error', () => { + eventCallbackListeners.delete(callbackListener); + }); + }); + + const eventCallbackServerStartupPromise = new Promise(resolve => { + eventCallbackServer.listen(0, () => { + const port = String((eventCallbackServer.address() as AddressInfo).port); + void registerCallbackServerPort(options.proxyServerName, port).then(resolve); + }); + }); + + await eventCallbackServerStartupPromise; + await proxyServerStartupPromise; + return; +} + +export async function waitForRequest( + proxyServerName: string, + callback: (eventData: SentryRequestCallbackData) => Promise | boolean, +): Promise { + const eventCallbackServerPort = await retrieveCallbackServerPort(proxyServerName); + + return new Promise((resolve, reject) => { + const request = http.request(`http://localhost:${eventCallbackServerPort}/`, {}, response => { + let eventContents = ''; + + response.on('error', err => { + reject(err); + }); + + response.on('data', (chunk: Buffer) => { + const chunkString = chunk.toString('utf8'); + chunkString.split('').forEach(char => { + if (char === '\n') { + const eventCallbackData: SentryRequestCallbackData = JSON.parse( + Buffer.from(eventContents, 'base64').toString('utf8'), + ); + const callbackResult = callback(eventCallbackData); + if (typeof callbackResult !== 'boolean') { + callbackResult.then( + match => { + if (match) { + response.destroy(); + resolve(eventCallbackData); + } + }, + err => { + throw err; + }, + ); + } else if (callbackResult) { + response.destroy(); + resolve(eventCallbackData); + } + eventContents = ''; + } else { + eventContents = eventContents.concat(char); + } + }); + }); + }); + + request.end(); + }); +} + +export function waitForEnvelopeItem( + proxyServerName: string, + callback: (envelopeItem: EnvelopeItem) => Promise | boolean, +): Promise { + return new Promise((resolve, reject) => { + waitForRequest(proxyServerName, async eventData => { + const envelopeItems = eventData.envelope[1]; + for (const envelopeItem of envelopeItems) { + if (await callback(envelopeItem)) { + resolve(envelopeItem); + return true; + } + } + return false; + }).catch(reject); + }); +} + +export function waitForError( + proxyServerName: string, + callback: (transactionEvent: Event) => Promise | boolean, +): Promise { + return new Promise((resolve, reject) => { + waitForEnvelopeItem(proxyServerName, async envelopeItem => { + const [envelopeItemHeader, envelopeItemBody] = envelopeItem; + if (envelopeItemHeader.type === 'event' && (await callback(envelopeItemBody as Event))) { + resolve(envelopeItemBody as Event); + return true; + } + return false; + }).catch(reject); + }); +} + +export function waitForTransaction( + proxyServerName: string, + callback: (transactionEvent: Event) => Promise | boolean, +): Promise { + return new Promise((resolve, reject) => { + waitForEnvelopeItem(proxyServerName, async envelopeItem => { + const [envelopeItemHeader, envelopeItemBody] = envelopeItem; + if (envelopeItemHeader.type === 'transaction' && (await callback(envelopeItemBody as Event))) { + resolve(envelopeItemBody as Event); + return true; + } + return false; + }).catch(reject); + }); +} + +const TEMP_FILE_PREFIX = 'event-proxy-server-'; + +async function registerCallbackServerPort(serverName: string, port: string): Promise { + const tmpFilePath = path.join(os.tmpdir(), `${TEMP_FILE_PREFIX}${serverName}`); + await writeFile(tmpFilePath, port, { encoding: 'utf8' }); +} + +function retrieveCallbackServerPort(serverName: string): Promise { + const tmpFilePath = path.join(os.tmpdir(), `${TEMP_FILE_PREFIX}${serverName}`); + return readFile(tmpFilePath, 'utf8'); +} diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json new file mode 100644 index 000000000000..99dfd693a272 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json @@ -0,0 +1,27 @@ +{ + "name": "node-express-app", + "version": "1.0.0", + "private": true, + "scripts": { + "start": "node --loader=@sentry/node/register src/app.mjs", + "clean": "npx rimraf node_modules,pnpm-lock.yaml", + "test:build": "pnpm install", + "test:assert": "playwright test" + }, + "dependencies": { + "@sentry/node": "latest || *", + "@sentry/types": "latest || *", + "express": "4.19.2", + "@types/express": "4.17.17", + "@types/node": "18.15.1", + "typescript": "4.9.5" + }, + "devDependencies": { + "@playwright/test": "^1.27.1", + "ts-node": "10.9.1" + }, + "volta": { + "extends": "../../package.json", + "node": "18.18.2" + } +} diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/playwright.config.ts b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/playwright.config.ts new file mode 100644 index 000000000000..8ac853fd11d0 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/playwright.config.ts @@ -0,0 +1,68 @@ +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; + +// Fix urls not resolving to localhost on Node v17+ +// See: https://github.com/axios/axios/issues/3821#issuecomment-1413727575 +import { setDefaultResultOrder } from 'dns'; +setDefaultResultOrder('ipv4first'); + +const eventProxyPort = 3031; +const expressPort = 3030; + +/** + * See https://playwright.dev/docs/test-configuration. + */ +const config: PlaywrightTestConfig = { + testDir: './tests', + /* Maximum time one test can run for. */ + timeout: 150_000, + expect: { + /** + * Maximum time expect() should wait for the condition to be met. + * For example in `await expect(locator).toHaveText();` + */ + timeout: 5000, + }, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: 0, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'list', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ + actionTimeout: 0, + + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: `http://localhost:${expressPort}`, + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + }, + }, + ], + + /* Run your local dev server before starting the tests */ + webServer: [ + { + command: 'pnpm ts-node-script start-event-proxy.ts', + port: eventProxyPort, + }, + { + command: 'pnpm start', + port: expressPort, + stdout: 'pipe', + stderr: 'pipe', + }, + ], +}; + +export default config; diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/src/app.mjs b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/src/app.mjs new file mode 100644 index 000000000000..8dc36dc7066b --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/src/app.mjs @@ -0,0 +1,49 @@ +import * as Sentry from '@sentry/node'; + +Sentry.init({ + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: process.env.E2E_TEST_DSN, + debug: true, + tunnel: `http://localhost:3031/`, // proxy server + tracesSampleRate: 1, +}); + +import express from 'express'; + +const app = express(); +const port = 3030; + +app.get('/test-success', function (req, res) { + setTimeout(() => { + res.status(200).end(); + }, 100); +}); + +app.get('/test-transaction/:param', function (req, res) { + setTimeout(() => { + res.status(200).end(); + }, 100); +}); + +app.get('/test-error', function (req, res) { + Sentry.captureException(new Error('This is an error')); + setTimeout(() => { + Sentry.flush(2000).then(() => { + res.status(200).end(); + }); + }, 100); +}); + +Sentry.setupExpressErrorHandler(app); + +// @ts-ignore +app.use(function onError(err, req, res, next) { + // The error id is attached to `res.sentry` to be returned + // and optionally displayed to the user for support. + res.statusCode = 500; + res.end(res.sentry + '\n'); +}); + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`); +}); diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/start-event-proxy.ts b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/start-event-proxy.ts new file mode 100644 index 000000000000..25ef6807cb93 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/start-event-proxy.ts @@ -0,0 +1,6 @@ +import { startEventProxyServer } from './event-proxy-server'; + +startEventProxyServer({ + port: 3031, + proxyServerName: 'esm-loader-node-express-app', +}); diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts new file mode 100644 index 000000000000..c9cef1a19e70 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts @@ -0,0 +1,33 @@ +import { expect, test } from '@playwright/test'; +import { waitForError, waitForTransaction } from '../event-proxy-server'; + +test('Should record exceptions captured inside handlers', async ({ request }) => { + const errorEventPromise = waitForError('esm-loader-node-express-app', errorEvent => { + return !!errorEvent?.exception?.values?.[0]?.value?.includes('This is an error'); + }); + + await request.get('/test-error'); + + await expect(errorEventPromise).resolves.toBeDefined(); +}); + +test('Should record a transaction for a parameterless route', async ({ request }) => { + const errorEventPromise = waitForTransaction('esm-loader-node-express-app', transactionEvent => { + console.log('txn', transactionEvent.transaction); + return transactionEvent?.transaction === 'GET /test-success'; + }); + + await request.get('/test-success'); + + await expect(errorEventPromise).resolves.toBeDefined(); +}); + +test('Should record a transaction for route with aparameters', async ({ request }) => { + const errorEventPromise = waitForTransaction('esm-loader-node-express-app', transactionEvent => { + return transactionEvent?.transaction === 'GET /test-transaction/:param'; + }); + + await request.get('/test-transaction/1'); + + await expect(errorEventPromise).resolves.toBeDefined(); +}); From 39e2c599a0e32d98fde5b9285e6622e2ff89bb62 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 28 Mar 2024 15:40:03 +0000 Subject: [PATCH 4/8] rename --- .../esm-loader-node-express-app/tests/server.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts index c9cef1a19e70..a41034ca1af4 100644 --- a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/tests/server.test.ts @@ -12,22 +12,22 @@ test('Should record exceptions captured inside handlers', async ({ request }) => }); test('Should record a transaction for a parameterless route', async ({ request }) => { - const errorEventPromise = waitForTransaction('esm-loader-node-express-app', transactionEvent => { + const transactionEventPromise = waitForTransaction('esm-loader-node-express-app', transactionEvent => { console.log('txn', transactionEvent.transaction); return transactionEvent?.transaction === 'GET /test-success'; }); await request.get('/test-success'); - await expect(errorEventPromise).resolves.toBeDefined(); + await expect(transactionEventPromise).resolves.toBeDefined(); }); test('Should record a transaction for route with aparameters', async ({ request }) => { - const errorEventPromise = waitForTransaction('esm-loader-node-express-app', transactionEvent => { + const transactionEventPromise = waitForTransaction('esm-loader-node-express-app', transactionEvent => { return transactionEvent?.transaction === 'GET /test-transaction/:param'; }); await request.get('/test-transaction/1'); - await expect(errorEventPromise).resolves.toBeDefined(); + await expect(transactionEventPromise).resolves.toBeDefined(); }); From 1f370508de8d8acfc1c7221cb397865ee20957ee Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 28 Mar 2024 15:56:22 +0000 Subject: [PATCH 5/8] better deps --- .../code/otelEsmLoaderTemplate.js | 2 ++ .../rollup-utils/code/otelLoaderTemplate.js | 1 - .../code/sentryNodeEsmLoaderTemplate.js | 2 ++ dev-packages/rollup-utils/npmHelpers.mjs | 19 ++++++++++++++----- packages/astro/package.json | 3 +-- packages/astro/rollup.npm.config.mjs | 2 +- packages/aws-serverless/package.json | 3 +-- packages/aws-serverless/rollup.npm.config.mjs | 2 +- packages/google-cloud-serverless/package.json | 3 +-- .../rollup.npm.config.mjs | 2 +- packages/nextjs/package.json | 1 - packages/nextjs/rollup.npm.config.mjs | 2 +- packages/node/package.json | 3 +-- packages/node/rollup.npm.config.mjs | 2 +- packages/remix/package.json | 1 - packages/remix/rollup.npm.config.mjs | 2 +- 16 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js delete mode 100644 dev-packages/rollup-utils/code/otelLoaderTemplate.js create mode 100644 dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js diff --git a/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js b/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js new file mode 100644 index 000000000000..117b7ad92cc0 --- /dev/null +++ b/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js @@ -0,0 +1,2 @@ +import { getFormat, getSource, load, resolve } from '@opentelemetry/instrumentation/hook.mjs'; +export { load, resolve, getFormat, getSource }; diff --git a/dev-packages/rollup-utils/code/otelLoaderTemplate.js b/dev-packages/rollup-utils/code/otelLoaderTemplate.js deleted file mode 100644 index b364ef0082c9..000000000000 --- a/dev-packages/rollup-utils/code/otelLoaderTemplate.js +++ /dev/null @@ -1 +0,0 @@ -export * from 'import-in-the-middle/hook.mjs'; diff --git a/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js b/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js new file mode 100644 index 000000000000..86c4b731472e --- /dev/null +++ b/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js @@ -0,0 +1,2 @@ +import { getFormat, getSource, load, resolve } from '@sentry/node/register'; +export { load, resolve, getFormat, getSource }; diff --git a/dev-packages/rollup-utils/npmHelpers.mjs b/dev-packages/rollup-utils/npmHelpers.mjs index b08dd8a3b908..20cd096efdfa 100644 --- a/dev-packages/rollup-utils/npmHelpers.mjs +++ b/dev-packages/rollup-utils/npmHelpers.mjs @@ -150,7 +150,11 @@ export function makeNPMConfigVariants(baseConfig, options = {}) { * This creates a loader file at the target location as part of the rollup build. * This loader script can then be used in combination with various Node.js flags (like --loader=...) to monkeypatch 3rd party modules. */ -export function makeOtelLoader(outputPath) { +export function makeOtelLoader(outputPath, hookVariant) { + if (hookVariant !== 'otel' && hookVariant !== 'sentry-node') { + throw new Error('hookVariant is neither "otel" nor "sentry-node". Pick one.'); + } + const foundLoaderExport = Object.keys(packageDotJSON.exports ?? {}).some(key => { return packageDotJSON?.exports?.[key]?.import?.default === outputPath; }); @@ -160,12 +164,13 @@ export function makeOtelLoader(outputPath) { ); } + const requiredDep = hookVariant === 'otel' ? '@opentelemetry/instrumentation' : '@sentry/node'; const foundImportInTheMiddleDep = Object.keys(packageDotJSON.dependencies ?? {}).some(key => { - return key === 'import-in-the-middle' && packageDotJSON?.dependencies?.[key] === '1.7.1'; + return key === requiredDep; }); if (!foundImportInTheMiddleDep) { throw new Error( - `You used the makeOtelLoader() rollup utility but didn't specify the "import-in-the-middle": "1.7.1" dependency in ${path.resolve( + `You used the makeOtelLoader() rollup utility but didn't specify the "${requiredDep}" dependency in ${path.resolve( process.cwd(), 'package.json', )}. Please add it to the dependencies.`, @@ -173,8 +178,12 @@ export function makeOtelLoader(outputPath) { } return defineConfig({ - input: path.join(__dirname, 'code', 'otelLoaderTemplate.js'), - external: ['import-in-the-middle/hook.mjs'], + input: path.join( + __dirname, + 'code', + hookVariant === 'otel' ? 'otelEsmLoaderTemplate.js' : 'sentryNodeEsmLoaderTemplate.js', + ), + external: ['@opentelemetry/instrumentation/hook.mjs', '@sentry/node/register'], output: { format: 'esm', file: outputPath, diff --git a/packages/astro/package.json b/packages/astro/package.json index 55699454253d..233b5a903701 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -60,8 +60,7 @@ "@sentry/node": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", - "@sentry/vite-plugin": "^2.14.2", - "import-in-the-middle": "1.7.1" + "@sentry/vite-plugin": "^2.14.2" }, "devDependencies": { "astro": "^3.5.0", diff --git a/packages/astro/rollup.npm.config.mjs b/packages/astro/rollup.npm.config.mjs index 92762b2b499c..b5987be16a8c 100644 --- a/packages/astro/rollup.npm.config.mjs +++ b/packages/astro/rollup.npm.config.mjs @@ -14,4 +14,4 @@ const variants = makeNPMConfigVariants( }), ); -export default [...variants, makeOtelLoader('./build/register.mjs')]; +export default [...variants, makeOtelLoader('./build/register.mjs', 'sentry-node')]; diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index 37dd5912227a..536c12d1894d 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -47,8 +47,7 @@ "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", "@types/aws-lambda": "^8.10.62", - "@types/express": "^4.17.14", - "import-in-the-middle": "1.7.1" + "@types/express": "^4.17.14" }, "devDependencies": { "@types/node": "^14.18.0", diff --git a/packages/aws-serverless/rollup.npm.config.mjs b/packages/aws-serverless/rollup.npm.config.mjs index d99f7ded86e8..67ed35f11ab6 100644 --- a/packages/aws-serverless/rollup.npm.config.mjs +++ b/packages/aws-serverless/rollup.npm.config.mjs @@ -12,5 +12,5 @@ export default [ }), { emitEsm: false }, ), - makeOtelLoader('./build/register.mjs'), + makeOtelLoader('./build/register.mjs', 'sentry-node'), ]; diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json index 49d426ed5be0..234a72ed1f36 100644 --- a/packages/google-cloud-serverless/package.json +++ b/packages/google-cloud-serverless/package.json @@ -47,8 +47,7 @@ "@sentry/node": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", - "@types/express": "^4.17.14", - "import-in-the-middle": "1.7.1" + "@types/express": "^4.17.14" }, "devDependencies": { "@google-cloud/bigquery": "^5.3.0", diff --git a/packages/google-cloud-serverless/rollup.npm.config.mjs b/packages/google-cloud-serverless/rollup.npm.config.mjs index 2d6da37d7610..4d511654b3b1 100644 --- a/packages/google-cloud-serverless/rollup.npm.config.mjs +++ b/packages/google-cloud-serverless/rollup.npm.config.mjs @@ -1,3 +1,3 @@ import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; -export default [...makeNPMConfigVariants(makeBaseNPMConfig()), makeOtelLoader('./build/register.mjs')]; +export default [...makeNPMConfigVariants(makeBaseNPMConfig()), makeOtelLoader('./build/register.mjs', 'sentry-node')]; diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index d56947dafda1..02f09cf98743 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -49,7 +49,6 @@ "@sentry/vercel-edge": "8.0.0-alpha.7", "@sentry/webpack-plugin": "2.16.0", "chalk": "3.0.0", - "import-in-the-middle": "1.7.1", "resolve": "1.22.8", "rollup": "3.29.4", "stacktrace-parser": "^0.1.10" diff --git a/packages/nextjs/rollup.npm.config.mjs b/packages/nextjs/rollup.npm.config.mjs index 8fc31d35d64f..96931b8f8afb 100644 --- a/packages/nextjs/rollup.npm.config.mjs +++ b/packages/nextjs/rollup.npm.config.mjs @@ -72,5 +72,5 @@ export default [ }, }), ), - makeOtelLoader('./build/register.mjs'), + makeOtelLoader('./build/register.mjs', 'sentry-node'), ]; diff --git a/packages/node/package.json b/packages/node/package.json index adc2ff570b49..d7b0dc38fba3 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -71,8 +71,7 @@ "@sentry/core": "8.0.0-alpha.7", "@sentry/opentelemetry": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", - "@sentry/utils": "8.0.0-alpha.7", - "import-in-the-middle": "1.7.1" + "@sentry/utils": "8.0.0-alpha.7" }, "devDependencies": { "@types/node": "^14.18.0" diff --git a/packages/node/rollup.npm.config.mjs b/packages/node/rollup.npm.config.mjs index 0568e8f32bb4..8e28541d64a9 100644 --- a/packages/node/rollup.npm.config.mjs +++ b/packages/node/rollup.npm.config.mjs @@ -5,7 +5,7 @@ import { createAnrWorkerCode } from './rollup.anr-worker.config.mjs'; const { workerRollupConfig, getBase64Code } = createAnrWorkerCode(); export default [ - makeOtelLoader('./build/register.mjs'), + makeOtelLoader('./build/register.mjs', 'otel'), // The worker needs to be built first since it's output is used in the main bundle. workerRollupConfig, ...makeNPMConfigVariants( diff --git a/packages/remix/package.json b/packages/remix/package.json index 848cb7d16104..bf2975485561 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -59,7 +59,6 @@ "@sentry/react": "8.0.0-alpha.7", "@sentry/types": "8.0.0-alpha.7", "@sentry/utils": "8.0.0-alpha.7", - "import-in-the-middle": "1.7.1", "glob": "^10.3.4", "yargs": "^17.6.0" }, diff --git a/packages/remix/rollup.npm.config.mjs b/packages/remix/rollup.npm.config.mjs index 4b2b0d1223f1..79803c84f486 100644 --- a/packages/remix/rollup.npm.config.mjs +++ b/packages/remix/rollup.npm.config.mjs @@ -13,5 +13,5 @@ export default [ }, }), ), - makeOtelLoader('./build/register.mjs'), + makeOtelLoader('./build/register.mjs', 'sentry-node'), ]; From a5ae9a16bce6cd45ec7ca41aab4b39b600faddcc Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 2 Apr 2024 07:17:39 +0000 Subject: [PATCH 6/8] Add disable test to ci --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca5452280d7c..a017b3d7add1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1037,6 +1037,7 @@ jobs: 'create-remix-app-v2', 'create-remix-app-express-vite-dev', 'debug-id-sourcemaps', + # 'esm-loader-node-express-app', # This is currently broken for upstream reasons. See https://github.com/getsentry/sentry-javascript/pull/11338#issuecomment-2025450675 'nextjs-app-dir', 'nextjs-14', 'react-create-hash-router', From 9236a80dd49896bf3b117e4cf1affce65b59076c Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 2 Apr 2024 10:05:20 +0000 Subject: [PATCH 7/8] Use `register` --- .../esm-loader-node-express-app/package.json | 4 ++-- dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js | 4 ++-- dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js | 3 +-- dev-packages/rollup-utils/npmHelpers.mjs | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json index 99dfd693a272..8ed10b0e6c58 100644 --- a/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json +++ b/dev-packages/e2e-tests/test-applications/esm-loader-node-express-app/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "private": true, "scripts": { - "start": "node --loader=@sentry/node/register src/app.mjs", + "start": "node --import=@sentry/node/register src/app.mjs", "clean": "npx rimraf node_modules,pnpm-lock.yaml", "test:build": "pnpm install", "test:assert": "playwright test" @@ -22,6 +22,6 @@ }, "volta": { "extends": "../../package.json", - "node": "18.18.2" + "node": "18.19.1" } } diff --git a/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js b/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js index 117b7ad92cc0..99c312a20ab4 100644 --- a/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js +++ b/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js @@ -1,2 +1,2 @@ -import { getFormat, getSource, load, resolve } from '@opentelemetry/instrumentation/hook.mjs'; -export { load, resolve, getFormat, getSource }; +import { register } from 'module'; +register('@opentelemetry/instrumentation/hook.mjs', import.meta.url); diff --git a/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js b/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js index 86c4b731472e..bb3f3084cbed 100644 --- a/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js +++ b/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js @@ -1,2 +1 @@ -import { getFormat, getSource, load, resolve } from '@sentry/node/register'; -export { load, resolve, getFormat, getSource }; +import '@sentry/node/register'; diff --git a/dev-packages/rollup-utils/npmHelpers.mjs b/dev-packages/rollup-utils/npmHelpers.mjs index 20cd096efdfa..bbd63e4ec621 100644 --- a/dev-packages/rollup-utils/npmHelpers.mjs +++ b/dev-packages/rollup-utils/npmHelpers.mjs @@ -148,7 +148,7 @@ export function makeNPMConfigVariants(baseConfig, options = {}) { /** * This creates a loader file at the target location as part of the rollup build. - * This loader script can then be used in combination with various Node.js flags (like --loader=...) to monkeypatch 3rd party modules. + * This loader script can then be used in combination with various Node.js flags (like --import=...) to monkeypatch 3rd party modules. */ export function makeOtelLoader(outputPath, hookVariant) { if (hookVariant !== 'otel' && hookVariant !== 'sentry-node') { From ab9ddc80d1679d410957234afb497507d3faf538 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 3 Apr 2024 09:37:28 +0000 Subject: [PATCH 8/8] Add secondary `hook` to support the --loader usecase --- .../code/otelEsmHooksLoaderTemplate.js | 2 + ...te.js => otelEsmRegisterLoaderTemplate.js} | 0 .../code/sentryNodeEsmHooksLoaderTemplate.js | 1 + .../code/sentryNodeEsmLoaderTemplate.js | 1 - .../sentryNodeEsmRegisterLoaderTemplate.js | 2 + dev-packages/rollup-utils/npmHelpers.mjs | 61 +++++++++++++------ packages/astro/package.json | 7 ++- packages/astro/rollup.npm.config.mjs | 4 +- packages/aws-serverless/package.json | 7 ++- packages/aws-serverless/rollup.npm.config.mjs | 4 +- packages/google-cloud-serverless/package.json | 7 ++- .../rollup.npm.config.mjs | 4 +- packages/nextjs/package.json | 7 ++- packages/nextjs/rollup.npm.config.mjs | 4 +- packages/node/package.json | 7 ++- packages/node/rollup.npm.config.mjs | 4 +- packages/remix/package.json | 7 ++- packages/remix/rollup.npm.config.mjs | 4 +- 18 files changed, 97 insertions(+), 36 deletions(-) create mode 100644 dev-packages/rollup-utils/code/otelEsmHooksLoaderTemplate.js rename dev-packages/rollup-utils/code/{otelEsmLoaderTemplate.js => otelEsmRegisterLoaderTemplate.js} (100%) create mode 100644 dev-packages/rollup-utils/code/sentryNodeEsmHooksLoaderTemplate.js delete mode 100644 dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js create mode 100644 dev-packages/rollup-utils/code/sentryNodeEsmRegisterLoaderTemplate.js diff --git a/dev-packages/rollup-utils/code/otelEsmHooksLoaderTemplate.js b/dev-packages/rollup-utils/code/otelEsmHooksLoaderTemplate.js new file mode 100644 index 000000000000..51c72d9d7192 --- /dev/null +++ b/dev-packages/rollup-utils/code/otelEsmHooksLoaderTemplate.js @@ -0,0 +1,2 @@ +import { getFormat, getSource, load, resolve } from '@opentelemetry/instrumentation/hook.mjs'; +export { getFormat, getSource, load, resolve }; diff --git a/dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js b/dev-packages/rollup-utils/code/otelEsmRegisterLoaderTemplate.js similarity index 100% rename from dev-packages/rollup-utils/code/otelEsmLoaderTemplate.js rename to dev-packages/rollup-utils/code/otelEsmRegisterLoaderTemplate.js diff --git a/dev-packages/rollup-utils/code/sentryNodeEsmHooksLoaderTemplate.js b/dev-packages/rollup-utils/code/sentryNodeEsmHooksLoaderTemplate.js new file mode 100644 index 000000000000..06fb71a76860 --- /dev/null +++ b/dev-packages/rollup-utils/code/sentryNodeEsmHooksLoaderTemplate.js @@ -0,0 +1 @@ +import '@sentry/node/hook'; diff --git a/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js b/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js deleted file mode 100644 index bb3f3084cbed..000000000000 --- a/dev-packages/rollup-utils/code/sentryNodeEsmLoaderTemplate.js +++ /dev/null @@ -1 +0,0 @@ -import '@sentry/node/register'; diff --git a/dev-packages/rollup-utils/code/sentryNodeEsmRegisterLoaderTemplate.js b/dev-packages/rollup-utils/code/sentryNodeEsmRegisterLoaderTemplate.js new file mode 100644 index 000000000000..5a9fa441f106 --- /dev/null +++ b/dev-packages/rollup-utils/code/sentryNodeEsmRegisterLoaderTemplate.js @@ -0,0 +1,2 @@ +import { getFormat, getSource, load, resolve } from '@sentry/node/register'; +export { getFormat, getSource, load, resolve }; diff --git a/dev-packages/rollup-utils/npmHelpers.mjs b/dev-packages/rollup-utils/npmHelpers.mjs index bbd63e4ec621..fa64ecbdb1d1 100644 --- a/dev-packages/rollup-utils/npmHelpers.mjs +++ b/dev-packages/rollup-utils/npmHelpers.mjs @@ -150,17 +150,28 @@ export function makeNPMConfigVariants(baseConfig, options = {}) { * This creates a loader file at the target location as part of the rollup build. * This loader script can then be used in combination with various Node.js flags (like --import=...) to monkeypatch 3rd party modules. */ -export function makeOtelLoader(outputPath, hookVariant) { +export function makeOtelLoaders(outputFolder, hookVariant) { if (hookVariant !== 'otel' && hookVariant !== 'sentry-node') { throw new Error('hookVariant is neither "otel" nor "sentry-node". Pick one.'); } - const foundLoaderExport = Object.keys(packageDotJSON.exports ?? {}).some(key => { - return packageDotJSON?.exports?.[key]?.import?.default === outputPath; + const expectedRegisterLoaderLocation = `${outputFolder}/register.mjs`; + const foundRegisterLoaderExport = Object.keys(packageDotJSON.exports ?? {}).some(key => { + return packageDotJSON?.exports?.[key]?.import?.default === expectedRegisterLoaderLocation; }); - if (!foundLoaderExport) { + if (!foundRegisterLoaderExport) { throw new Error( - `You used the makeOtelLoader() rollup utility without specifying the loader inside \`exports[something].import.default\`. Please add "${outputPath}" as a value there (maybe check for typos - it needs to be "${outputPath}" exactly).`, + `You used the makeOtelLoaders() rollup utility without specifying the register loader inside \`exports[something].import.default\`. Please add "${expectedRegisterLoaderLocation}" as a value there (maybe check for typos - it needs to be "${expectedRegisterLoaderLocation}" exactly).`, + ); + } + + const expectedHooksLoaderLocation = `${outputFolder}/hook.mjs`; + const foundHookLoaderExport = Object.keys(packageDotJSON.exports ?? {}).some(key => { + return packageDotJSON?.exports?.[key]?.import?.default === expectedHooksLoaderLocation; + }); + if (!foundHookLoaderExport) { + throw new Error( + `You used the makeOtelLoaders() rollup utility without specifying the hook loader inside \`exports[something].import.default\`. Please add "${expectedHooksLoaderLocation}" as a value there (maybe check for typos - it needs to be "${expectedHooksLoaderLocation}" exactly).`, ); } @@ -170,23 +181,39 @@ export function makeOtelLoader(outputPath, hookVariant) { }); if (!foundImportInTheMiddleDep) { throw new Error( - `You used the makeOtelLoader() rollup utility but didn't specify the "${requiredDep}" dependency in ${path.resolve( + `You used the makeOtelLoaders() rollup utility but didn't specify the "${requiredDep}" dependency in ${path.resolve( process.cwd(), 'package.json', )}. Please add it to the dependencies.`, ); } - return defineConfig({ - input: path.join( - __dirname, - 'code', - hookVariant === 'otel' ? 'otelEsmLoaderTemplate.js' : 'sentryNodeEsmLoaderTemplate.js', - ), - external: ['@opentelemetry/instrumentation/hook.mjs', '@sentry/node/register'], - output: { - format: 'esm', - file: outputPath, + return defineConfig([ + // register() hook + { + input: path.join( + __dirname, + 'code', + hookVariant === 'otel' ? 'otelEsmRegisterLoaderTemplate.js' : 'sentryNodeEsmRegisterLoaderTemplate.js', + ), + external: ['@opentelemetry/instrumentation/hook.mjs', '@sentry/node/register'], + output: { + format: 'esm', + file: path.join(outputFolder, 'register.mjs'), + }, }, - }); + // --loader hook + { + input: path.join( + __dirname, + 'code', + hookVariant === 'otel' ? 'otelEsmHooksLoaderTemplate.js' : 'sentryNodeEsmHooksLoaderTemplate.js', + ), + external: ['@opentelemetry/instrumentation/hook.mjs', '@sentry/node/hook'], + output: { + format: 'esm', + file: path.join(outputFolder, 'hook.mjs'), + }, + }, + ]); } diff --git a/packages/astro/package.json b/packages/astro/package.json index 233b5a903701..ecdfa6fc06a7 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -46,7 +46,12 @@ "import": { "default": "./build/register.mjs" } - } + }, +"./hook": { + "import": { + "default": "./build/hook.mjs" + } +} }, "publishConfig": { "access": "public" diff --git a/packages/astro/rollup.npm.config.mjs b/packages/astro/rollup.npm.config.mjs index b5987be16a8c..ca3b338433a7 100644 --- a/packages/astro/rollup.npm.config.mjs +++ b/packages/astro/rollup.npm.config.mjs @@ -1,4 +1,4 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoaders } from '@sentry-internal/rollup-utils'; const variants = makeNPMConfigVariants( makeBaseNPMConfig({ @@ -14,4 +14,4 @@ const variants = makeNPMConfigVariants( }), ); -export default [...variants, makeOtelLoader('./build/register.mjs', 'sentry-node')]; +export default [...variants, ...makeOtelLoaders('./build', 'sentry-node')]; diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index 536c12d1894d..7109d496c13a 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -29,7 +29,12 @@ "import": { "default": "./build/register.mjs" } - } + }, +"./hook": { + "import": { + "default": "./build/hook.mjs" + } +} }, "typesVersions": { "<4.9": { diff --git a/packages/aws-serverless/rollup.npm.config.mjs b/packages/aws-serverless/rollup.npm.config.mjs index 67ed35f11ab6..59af857e3c0a 100644 --- a/packages/aws-serverless/rollup.npm.config.mjs +++ b/packages/aws-serverless/rollup.npm.config.mjs @@ -1,4 +1,4 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoaders } from '@sentry-internal/rollup-utils'; export default [ ...makeNPMConfigVariants( @@ -12,5 +12,5 @@ export default [ }), { emitEsm: false }, ), - makeOtelLoader('./build/register.mjs', 'sentry-node'), + ...makeOtelLoaders('./build', 'sentry-node'), ]; diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json index 234a72ed1f36..0519c5efae32 100644 --- a/packages/google-cloud-serverless/package.json +++ b/packages/google-cloud-serverless/package.json @@ -30,7 +30,12 @@ "import": { "default": "./build/register.mjs" } - } + }, +"./hook": { + "import": { + "default": "./build/hook.mjs" + } +} }, "typesVersions": { "<4.9": { diff --git a/packages/google-cloud-serverless/rollup.npm.config.mjs b/packages/google-cloud-serverless/rollup.npm.config.mjs index 4d511654b3b1..5e0b74554d96 100644 --- a/packages/google-cloud-serverless/rollup.npm.config.mjs +++ b/packages/google-cloud-serverless/rollup.npm.config.mjs @@ -1,3 +1,3 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoaders } from '@sentry-internal/rollup-utils'; -export default [...makeNPMConfigVariants(makeBaseNPMConfig()), makeOtelLoader('./build/register.mjs', 'sentry-node')]; +export default [...makeNPMConfigVariants(makeBaseNPMConfig()), ...makeOtelLoaders('./build', 'sentry-node')]; diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 02f09cf98743..1dbb1509b55c 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -27,7 +27,12 @@ "import": { "default": "./build/register.mjs" } - } + }, +"./hook": { + "import": { + "default": "./build/hook.mjs" + } +} }, "typesVersions": { "<4.9": { diff --git a/packages/nextjs/rollup.npm.config.mjs b/packages/nextjs/rollup.npm.config.mjs index 96931b8f8afb..afe41659238f 100644 --- a/packages/nextjs/rollup.npm.config.mjs +++ b/packages/nextjs/rollup.npm.config.mjs @@ -1,4 +1,4 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoaders } from '@sentry-internal/rollup-utils'; export default [ ...makeNPMConfigVariants( @@ -72,5 +72,5 @@ export default [ }, }), ), - makeOtelLoader('./build/register.mjs', 'sentry-node'), + ...makeOtelLoaders('./build', 'sentry-node'), ]; diff --git a/packages/node/package.json b/packages/node/package.json index d7b0dc38fba3..938dd837ad81 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -35,7 +35,12 @@ "import": { "default": "./build/register.mjs" } - } + }, +"./hook": { + "import": { + "default": "./build/hook.mjs" + } +} }, "typesVersions": { "<4.9": { diff --git a/packages/node/rollup.npm.config.mjs b/packages/node/rollup.npm.config.mjs index 8e28541d64a9..443661d2882a 100644 --- a/packages/node/rollup.npm.config.mjs +++ b/packages/node/rollup.npm.config.mjs @@ -1,11 +1,11 @@ import replace from '@rollup/plugin-replace'; -import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoaders } from '@sentry-internal/rollup-utils'; import { createAnrWorkerCode } from './rollup.anr-worker.config.mjs'; const { workerRollupConfig, getBase64Code } = createAnrWorkerCode(); export default [ - makeOtelLoader('./build/register.mjs', 'otel'), + ...makeOtelLoaders('./build', 'otel'), // The worker needs to be built first since it's output is used in the main bundle. workerRollupConfig, ...makeNPMConfigVariants( diff --git a/packages/remix/package.json b/packages/remix/package.json index bf2975485561..9d8d4b80f294 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -38,7 +38,12 @@ "import": { "default": "./build/register.mjs" } - } + }, +"./hook": { + "import": { + "default": "./build/hook.mjs" + } +} }, "typesVersions": { "<4.9": { diff --git a/packages/remix/rollup.npm.config.mjs b/packages/remix/rollup.npm.config.mjs index 79803c84f486..b705fba0c55f 100644 --- a/packages/remix/rollup.npm.config.mjs +++ b/packages/remix/rollup.npm.config.mjs @@ -1,4 +1,4 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoader } from '@sentry-internal/rollup-utils'; +import { makeBaseNPMConfig, makeNPMConfigVariants, makeOtelLoaders } from '@sentry-internal/rollup-utils'; export default [ ...makeNPMConfigVariants( @@ -13,5 +13,5 @@ export default [ }, }), ), - makeOtelLoader('./build/register.mjs', 'sentry-node'), + ...makeOtelLoaders('./build', 'sentry-node'), ];