Skip to content

fix(profiling-node): Only emit CJS and support ESM via import(cjs) #15150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import esbuild from 'esbuild';

console.log('Running build using esbuild version', esbuild.version);

const output = esbuild.buildSync({
logLevel: 'debug',
platform: 'node',
entryPoints: ['./index.js'],
outfile: './dist/esbuild/index.js',
target: 'esnext',
format: 'cjs',
bundle: true,
loader: { '.node': 'copy' },
});

process.exit(output.errors.length);
31 changes: 31 additions & 0 deletions dev-packages/e2e-tests/test-applications/node-profiling/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const Sentry = require('@sentry/node');
const { nodeProfilingIntegration } = require('@sentry/profiling-node');
const { inspect } = require('util');

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

function transport(_) {
return {
send(envelope) {
// eslint-disable-next-line no-console
console.log(inspect(envelope, false, null, true));
return Promise.resolve({ statusCode: 200 });
},
flush() {
return new Promise(resolve => setTimeout(() => resolve(true), 1000));
},
};
}

Sentry.init({
debug: true,
dsn: 'https://7fa19397baaf433f919fbe02228d5470@o1137848.ingest.sentry.io/6625302',
integrations: [nodeProfilingIntegration()],
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
transport,
});

Sentry.startSpan({ name: 'Precompile test' }, async () => {
await wait(500);
});
15 changes: 0 additions & 15 deletions dev-packages/e2e-tests/test-applications/node-profiling/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
"version": "1.0.0",
"private": true,
"scripts": {
"typecheck": "tsc --noEmit",
"build": "node build-cjs.mjs && node build-esm.mjs",
"test": "node dist/cjs/index.js && node --experimental-require-module dist/cjs/index.js && node dist/esm/index.mjs",
"test": "node dist/cjs/index.js && node dist/cjs/index.js && node dist/esm/index.mjs",
"clean": "npx rimraf node_modules dist",
"test:electron": "$(pnpm bin)/electron-rebuild && playwright test",
"test:build": "pnpm run typecheck && pnpm run build",
"test:assert": "pnpm run test && pnpm run test:electron"
"test:build": "npm run test:build:esbuild && npm run test:build:webpack",
"test:build:webpack": "webpack --config webpack.config.mjs",
"test:build:esbuild": "node esbuild.mjs",
"test:assert": "npm run test:assert:esbuild && npm run test:assert:webpack",
"test:assert:esbuild": "node dist/esbuild/index.js",
"test:assert:webpack": "node dist/webpack/index.js"
},
"dependencies": {
"@electron/rebuild": "^3.7.0",
Expand All @@ -18,7 +20,10 @@
"@sentry/node": "latest || *",
"@sentry/profiling-node": "latest || *",
"electron": "^33.2.0",
"esbuild": "0.20.0"
"esbuild": "0.24.2",
"webpack": "5.97.1",
"webpack-cli": "6.0.1",
"node-loader": "2.1.0"
},
"volta": {
"extends": "../../package.json"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as path from 'path';

const __dirname = path.dirname(new URL(import.meta.url).pathname);

export default {
mode: 'production',
entry: './index.js',
target: 'node',
output: {
path: path.resolve(__dirname, 'dist', 'webpack'),
filename: 'index.js',
},
resolve: {
extensions: ['.js', '.node'],
},
module: {
rules: [
{
test: /\.node$/,
loader: 'node-loader',
},
],
},
};
2 changes: 2 additions & 0 deletions packages/profiling-node/lib/esm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { nodeProfilingIntegration } from '../cjs/index.js';
export { nodeProfilingIntegration };
3 changes: 3 additions & 0 deletions packages/profiling-node/lib/esm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
3 changes: 3 additions & 0 deletions packages/profiling-node/rollup.npm.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ export default makeNPMConfigVariants(
],
},
}),
{
emitEsm: false,
},
);
80 changes: 32 additions & 48 deletions packages/profiling-node/src/cpu_profiler.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { createRequire } from 'node:module';
import { arch as _arch, platform as _platform } from 'node:os';
import { join, resolve } from 'node:path';
import { dirname } from 'node:path';
import { env, versions } from 'node:process';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { threadId } from 'node:worker_threads';
import { familySync } from 'detect-libc';
import { getAbi } from 'node-abi';
Expand All @@ -18,8 +15,6 @@ import type {
} from './types';
import type { ProfileFormat } from './types';

declare const __IMPORT_META_URL_REPLACEMENT__: string;

const stdlib = familySync();
const platform = process.env['BUILD_PLATFORM'] || _platform();
const arch = process.env['BUILD_ARCH'] || _arch();
Expand All @@ -31,76 +26,65 @@ const identifier = [platform, arch, stdlib, abi].filter(c => c !== undefined &&
*/
// eslint-disable-next-line complexity
export function importCppBindingsModule(): PrivateV8CpuProfilerBindings {
// We need to work around using import.meta.url directly with __IMPORT_META_URL_REPLACEMENT__ because jest complains about it.
const importMetaUrl =
typeof __IMPORT_META_URL_REPLACEMENT__ !== 'undefined'
? // This case is always hit when the SDK is built
__IMPORT_META_URL_REPLACEMENT__
: // This case is hit when the tests are run
pathToFileURL(__filename).href;

const createdRequire = createRequire(importMetaUrl);
const esmCompatibleDirname = dirname(fileURLToPath(importMetaUrl));

// If a binary path is specified, use that.
if (env['SENTRY_PROFILER_BINARY_PATH']) {
const envPath = env['SENTRY_PROFILER_BINARY_PATH'];
return createdRequire(envPath);
return require(envPath);
}

// If a user specifies a different binary dir, they are in control of the binaries being moved there
if (env['SENTRY_PROFILER_BINARY_DIR']) {
const binaryPath = join(resolve(env['SENTRY_PROFILER_BINARY_DIR']), `sentry_cpu_profiler-${identifier}`);
return createdRequire(`${binaryPath}.node`);
return require(`${binaryPath}.node`);
}

// We need the fallthrough so that in the end, we can fallback to the dynamic require.
// This is for cases where precompiled binaries were not provided, but may have been compiled from source.
if (platform === 'darwin') {
if (arch === 'x64') {
if (abi === '93') {
return createdRequire('../sentry_cpu_profiler-darwin-x64-93.node');
return require('../sentry_cpu_profiler-darwin-x64-93.node');
}
if (abi === '108') {
return createdRequire('../sentry_cpu_profiler-darwin-x64-108.node');
return require('../sentry_cpu_profiler-darwin-x64-108.node');
}
if (abi === '115') {
return createdRequire('../sentry_cpu_profiler-darwin-x64-115.node');
return require('../sentry_cpu_profiler-darwin-x64-115.node');
}
if (abi === '127') {
return createdRequire('../sentry_cpu_profiler-darwin-x64-127.node');
return require('../sentry_cpu_profiler-darwin-x64-127.node');
}
}

if (arch === 'arm64') {
if (abi === '93') {
return createdRequire('../sentry_cpu_profiler-darwin-arm64-93.node');
return require('../sentry_cpu_profiler-darwin-arm64-93.node');
}
if (abi === '108') {
return createdRequire('../sentry_cpu_profiler-darwin-arm64-108.node');
return require('../sentry_cpu_profiler-darwin-arm64-108.node');
}
if (abi === '115') {
return createdRequire('../sentry_cpu_profiler-darwin-arm64-115.node');
return require('../sentry_cpu_profiler-darwin-arm64-115.node');
}
if (abi === '127') {
return createdRequire('../sentry_cpu_profiler-darwin-arm64-127.node');
return require('../sentry_cpu_profiler-darwin-arm64-127.node');
}
}
}

if (platform === 'win32') {
if (arch === 'x64') {
if (abi === '93') {
return createdRequire('../sentry_cpu_profiler-win32-x64-93.node');
return require('../sentry_cpu_profiler-win32-x64-93.node');
}
if (abi === '108') {
return createdRequire('../sentry_cpu_profiler-win32-x64-108.node');
return require('../sentry_cpu_profiler-win32-x64-108.node');
}
if (abi === '115') {
return createdRequire('../sentry_cpu_profiler-win32-x64-115.node');
return require('../sentry_cpu_profiler-win32-x64-115.node');
}
if (abi === '127') {
return createdRequire('../sentry_cpu_profiler-win32-x64-127.node');
return require('../sentry_cpu_profiler-win32-x64-127.node');
}
}
}
Expand All @@ -109,68 +93,68 @@ export function importCppBindingsModule(): PrivateV8CpuProfilerBindings {
if (arch === 'x64') {
if (stdlib === 'musl') {
if (abi === '93') {
return createdRequire('../sentry_cpu_profiler-linux-x64-musl-93.node');
return require('../sentry_cpu_profiler-linux-x64-musl-93.node');
}
if (abi === '108') {
return createdRequire('../sentry_cpu_profiler-linux-x64-musl-108.node');
return require('../sentry_cpu_profiler-linux-x64-musl-108.node');
}
if (abi === '115') {
return createdRequire('../sentry_cpu_profiler-linux-x64-musl-115.node');
return require('../sentry_cpu_profiler-linux-x64-musl-115.node');
}
if (abi === '127') {
return createdRequire('../sentry_cpu_profiler-linux-x64-musl-127.node');
return require('../sentry_cpu_profiler-linux-x64-musl-127.node');
}
}
if (stdlib === 'glibc') {
if (abi === '93') {
return createdRequire('../sentry_cpu_profiler-linux-x64-glibc-93.node');
return require('../sentry_cpu_profiler-linux-x64-glibc-93.node');
}
if (abi === '108') {
return createdRequire('../sentry_cpu_profiler-linux-x64-glibc-108.node');
return require('../sentry_cpu_profiler-linux-x64-glibc-108.node');
}
if (abi === '115') {
return createdRequire('../sentry_cpu_profiler-linux-x64-glibc-115.node');
return require('../sentry_cpu_profiler-linux-x64-glibc-115.node');
}
if (abi === '127') {
return createdRequire('../sentry_cpu_profiler-linux-x64-glibc-127.node');
return require('../sentry_cpu_profiler-linux-x64-glibc-127.node');
}
}
}
if (arch === 'arm64') {
if (stdlib === 'musl') {
if (abi === '93') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-musl-93.node');
return require('../sentry_cpu_profiler-linux-arm64-musl-93.node');
}
if (abi === '108') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-musl-108.node');
return require('../sentry_cpu_profiler-linux-arm64-musl-108.node');
}
if (abi === '115') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-musl-115.node');
return require('../sentry_cpu_profiler-linux-arm64-musl-115.node');
}
if (abi === '127') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-musl-127.node');
return require('../sentry_cpu_profiler-linux-arm64-musl-127.node');
}
}

if (stdlib === 'glibc') {
if (abi === '93') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-glibc-93.node');
return require('../sentry_cpu_profiler-linux-arm64-glibc-93.node');
}
if (abi === '108') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-glibc-108.node');
return require('../sentry_cpu_profiler-linux-arm64-glibc-108.node');
}
if (abi === '115') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-glibc-115.node');
return require('../sentry_cpu_profiler-linux-arm64-glibc-115.node');
}
if (abi === '127') {
return createdRequire('../sentry_cpu_profiler-linux-arm64-glibc-127.node');
return require('../sentry_cpu_profiler-linux-arm64-glibc-127.node');
}
}
}
}

const built_from_source_path = resolve(esmCompatibleDirname, '..', `sentry_cpu_profiler-${identifier}`);
return createdRequire(`${built_from_source_path}.node`);
const built_from_source_path = resolve(__dirname, '..', `sentry_cpu_profiler-${identifier}`);
return require(`${built_from_source_path}.node`);
}

const PrivateCpuProfilerBindings: PrivateV8CpuProfilerBindings = importCppBindingsModule();
Expand Down
Loading