Skip to content

Commit 2bf97e2

Browse files
committed
chore: Switch to rolldown
1 parent f9b8bad commit 2bf97e2

95 files changed

Lines changed: 1030 additions & 909 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.size-limit.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,15 +364,15 @@ module.exports = [
364364
path: createCDNPath('bundle.tracing.replay.feedback.min.js'),
365365
gzip: false,
366366
brotli: false,
367-
limit: '295 KB',
367+
limit: '297 KB',
368368
disablePlugins: ['@size-limit/esbuild'],
369369
},
370370
{
371371
name: 'CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed',
372372
path: createCDNPath('bundle.tracing.replay.feedback.logs.metrics.min.js'),
373373
gzip: false,
374374
brotli: false,
375-
limit: '301 KB',
375+
limit: '303 KB',
376376
disablePlugins: ['@size-limit/esbuild'],
377377
},
378378
// Next.js SDK (ESM)

‎dev-packages/e2e-tests/test-applications/nextjs-16/tests/worker-bundle.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function readOrchestrionPluginGraphSources(): string[] {
5656
const entrySource = fs.readFileSync(pluginEntry, 'utf8');
5757
return [
5858
entrySource,
59-
...[...entrySource.matchAll(/require\('(\.\.?\/[^']+)'\)/g)].map(([, specifier]) =>
59+
...[...entrySource.matchAll(/require\(['"](\.\.?\/[^'"]+)['"]\)/g)].map(([, specifier]) =>
6060
fs.readFileSync(path.resolve(path.dirname(pluginEntry), specifier), 'utf8'),
6161
),
6262
];

‎dev-packages/e2e-tests/test-applications/node-rolldown/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"devDependencies": {
1818
"@sentry-internal/test-utils": "link:../../../test-utils",
1919
"graphql": "16.9.0",
20-
"rolldown": "1.2.5"
20+
"rolldown": "1.2.14"
2121
},
2222
"volta": {
2323
"extends": "../../package.json"

‎dev-packages/node-integration-tests/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"scripts": {
1313
"build": "run-s build:transpile build:types",
1414
"build:dev": "yarn build",
15-
"build:transpile": "rollup -c rollup.npm.config.mjs",
15+
"build:transpile": "rolldown -c rollup.npm.config.mjs",
1616
"build:types": "tsc -p tsconfig.types.json",
1717
"clean": "rimraf -g suites/**/node_modules suites/**/tmp_* && run-p clean:script",
1818
"clean:script": "node scripts/clean.js",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as Sentry from '@sentry/node';
2+
3+
// `Sentry.init()` synchronously calls `registerDiagnosticsChannelInjection()`, which reaches the
4+
// vendored orchestrion transformer. That chain is split so a bundler can tree-shake it (see
5+
// `makeCjsExportsSplitPlugin` in server-utils' rollup config); this asserts the split degrades to
6+
// "no channel injection" rather than throwing when the bundler drops it.
7+
Sentry.init({
8+
dsn: 'https://public@dsn.ingest.sentry.io/1337',
9+
tracesSampleRate: 0,
10+
autoSessionTracking: false,
11+
});
12+
13+
// eslint-disable-next-line no-console
14+
console.log(`SENTRY_NODE_INITIALIZED client=${Boolean(Sentry.getClient())}`);

‎dev-packages/node-integration-tests/suites/esbuild/test.ts‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,34 @@ describe('esbuild bundling', () => {
3232
rmSync(outDir, { recursive: true, force: true });
3333
}
3434
});
35+
36+
test('@sentry/node survives init() when bundled to ESM with tree-shaking', async () => {
37+
const outDir = mkdtempSync(join(tmpdir(), 'sentry-esbuild-esm-'));
38+
const outfile = join(outDir, 'bundle.mjs');
39+
40+
try {
41+
await build({
42+
entryPoints: [join(__dirname, 'app-init.ts')],
43+
outfile,
44+
platform: 'node',
45+
format: 'esm',
46+
bundle: true,
47+
// `@sentry/server-utils` is `sideEffects: false`, so this is where a bundler is free to
48+
// drop the vendored orchestrion transformer.
49+
treeShaking: true,
50+
logLevel: 'silent',
51+
});
52+
53+
const result = spawnSync('node', [outfile], { encoding: 'utf-8' });
54+
55+
// Dropping the transformer must not take `init()` with it: reading a tree-shaken CJS
56+
// container has to yield `undefined`, not throw on destructuring or on a call.
57+
expect(result.stderr).not.toContain('Cannot destructure');
58+
expect(result.stderr).not.toContain('is not a function');
59+
expect(result.status).toBe(0);
60+
expect(result.stdout).toContain('SENTRY_NODE_INITIALIZED client=true');
61+
} finally {
62+
rmSync(outDir, { recursive: true, force: true });
63+
}
64+
});
3565
});

‎dev-packages/rollup-utils/bundleHelpers.mjs‎

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,50 @@
11
/**
2-
* Rollup config docs: https://rollupjs.org/guide/en/#big-list-of-options
2+
* Rolldown config docs: https://rolldown.rs/reference/config-options
33
*/
44

5-
import { builtinModules } from 'module';
5+
import * as fs from 'fs';
6+
import * as path from 'path';
67

78
import deepMerge from 'deepmerge';
89

910
import {
11+
makeBannerOptions,
1012
makeBrowserBuildPlugin,
11-
makeCommonJSPlugin,
12-
makeEsbuildPlugin,
1313
makeIsDebugBuildPlugin,
14-
makeLicensePlugin,
15-
makeNodeResolvePlugin,
14+
makeMinifierOptions,
1615
makeRrwebBuildPlugin,
1716
makeSetSDKSourcePlugin,
18-
makeTerserPlugin,
1917
} from './plugins/index.mjs';
20-
import { mergePlugins } from './utils.mjs';
18+
import { getNodeBuiltIns, mergePlugins, treeShakePreset } from './utils.mjs';
2119
import { makeProductionReplacePlugin } from './plugins/npmPlugins.mjs';
2220

2321
const BUNDLE_VARIANTS = ['.js', '.min.js', '.debug.min.js'];
2422

23+
const packageDotJSON = JSON.parse(fs.readFileSync(path.resolve(process.cwd(), './package.json'), { encoding: 'utf8' }));
24+
2525
export function makeBaseBundleConfig(options) {
26-
const { bundleType, entrypoints, licenseTitle, outputFileBase, packageSpecificConfig, esbuild } = options;
26+
const { bundleType, entrypoints, licenseTitle, outputFileBase, packageSpecificConfig } = options;
2727

28-
const nodeResolvePlugin = makeNodeResolvePlugin();
29-
const transpilePlugin = makeEsbuildPlugin(esbuild);
3028
const markAsBrowserBuildPlugin = makeBrowserBuildPlugin(true);
31-
const licensePlugin = makeLicensePlugin(licenseTitle);
29+
const banner = makeBannerOptions(licenseTitle, packageDotJSON.version);
3230
const rrwebBuildPlugin = makeRrwebBuildPlugin({
3331
excludeIframe: false,
3432
excludeShadowDom: false,
3533
});
3634
const productionReplacePlugin = makeProductionReplacePlugin();
3735

38-
// The `commonjs` plugin is the `esModuleInterop` of the bundling world. When used with `transformMixedEsModules`, it
39-
// will include all dependencies, imported or required, in the final bundle. (Without it, CJS modules aren't included
40-
// at all, and without `transformMixedEsModules`, they're only included if they're imported, not if they're required.)
41-
const commonJSPlugin = makeCommonJSPlugin({ transformMixedEsModules: true });
42-
4336
// used by `@sentry/browser`
4437
const standAloneBundleConfig = {
4538
output: {
39+
banner,
4640
format: 'iife',
4741
name: 'Sentry',
4842
intro: () => {
4943
return 'exports = window.Sentry || {};';
5044
},
5145
},
5246
context: 'window',
53-
plugins: [rrwebBuildPlugin, markAsBrowserBuildPlugin, licensePlugin],
47+
plugins: [rrwebBuildPlugin, markAsBrowserBuildPlugin],
5448
};
5549

5650
// used by `@sentry/wasm` & pluggable integrations from core/browser (bundles which need to be combined with a stand-alone SDK bundle)
@@ -61,7 +55,7 @@ export function makeBaseBundleConfig(options) {
6155
format: 'cjs',
6256

6357
// code to add before the CJS wrapper
64-
banner: '(function (__window) {',
58+
banner: `${banner}\n(function (__window) {`,
6559

6660
// code to add just inside the CJS wrapper, before any of the wrapped code
6761
intro: 'var exports = {};',
@@ -84,30 +78,41 @@ export function makeBaseBundleConfig(options) {
8478
// code to add after the CJS wrapper
8579
footer: '}(window));',
8680
},
87-
plugins: [rrwebBuildPlugin, markAsBrowserBuildPlugin, licensePlugin],
81+
plugins: [rrwebBuildPlugin, markAsBrowserBuildPlugin],
8882
};
8983

9084
const workerBundleConfig = {
9185
output: {
86+
banner,
9287
format: 'esm',
88+
minify: makeMinifierOptions(),
9389
},
94-
plugins: [commonJSPlugin, makeTerserPlugin(), licensePlugin],
9590
// Don't bundle any of Node's core modules
96-
external: builtinModules,
91+
external: getNodeBuiltIns(),
9792
};
9893

9994
const awsLambdaExtensionBundleConfig = {
10095
output: {
10196
format: 'esm',
97+
minify: makeMinifierOptions(),
10298
},
103-
plugins: [commonJSPlugin, makeIsDebugBuildPlugin(true), makeTerserPlugin()],
99+
plugins: [makeIsDebugBuildPlugin(true)],
104100
// Don't bundle any of Node's core modules
105-
external: builtinModules,
101+
external: getNodeBuiltIns(),
106102
};
107103

108104
// used by all bundles
109105
const sharedBundleConfig = {
110106
input: entrypoints,
107+
108+
// Point at the package's tsconfig so rolldown picks up its TypeScript & JSX settings.
109+
tsconfig: path.resolve(process.cwd(), './tsconfig.json'),
110+
111+
// ES2020 is our floor: keeps `?.`/`??` native and downlevels everything newer.
112+
transform: {
113+
target: 'es2020',
114+
},
115+
111116
output: {
112117
// a file extension will be added to this base value when we specify either a minified or non-minified build
113118
entryFileNames: outputFileBase,
@@ -116,8 +121,8 @@ export function makeBaseBundleConfig(options) {
116121
strict: false,
117122
esModule: false,
118123
},
119-
plugins: [productionReplacePlugin, transpilePlugin, nodeResolvePlugin],
120-
treeshake: 'smallest',
124+
plugins: [productionReplacePlugin],
125+
treeshake: treeShakePreset('smallest'),
121126
};
122127

123128
const bundleTypeConfigMap = {
@@ -147,7 +152,7 @@ export function makeBundleConfigVariants(baseConfig, options = {}) {
147152

148153
const includeDebuggingPlugin = makeIsDebugBuildPlugin(true);
149154
const stripDebuggingPlugin = makeIsDebugBuildPlugin(false);
150-
const terserPlugin = makeTerserPlugin();
155+
const minify = makeMinifierOptions();
151156
const setSdkSourcePlugin = makeSetSDKSourcePlugin('cdn');
152157

153158
// The additional options to use for each variant we're going to create.
@@ -162,15 +167,17 @@ export function makeBundleConfigVariants(baseConfig, options = {}) {
162167
'.min.js': {
163168
output: {
164169
entryFileNames: chunkInfo => `${baseConfig.output.entryFileNames(chunkInfo)}.min.js`,
170+
minify,
165171
},
166-
plugins: [stripDebuggingPlugin, setSdkSourcePlugin, terserPlugin],
172+
plugins: [stripDebuggingPlugin, setSdkSourcePlugin],
167173
},
168174

169175
'.debug.min.js': {
170176
output: {
171177
entryFileNames: chunkInfo => `${baseConfig.output.entryFileNames(chunkInfo)}.debug.min.js`,
178+
minify,
172179
},
173-
plugins: [includeDebuggingPlugin, setSdkSourcePlugin, terserPlugin],
180+
plugins: [includeDebuggingPlugin, setSdkSourcePlugin],
174181
},
175182
};
176183

‎dev-packages/rollup-utils/index.mjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ export { plugins };
44

55
export * from './bundleHelpers.mjs';
66
export * from './npmHelpers.mjs';
7-
export { insertAt } from './utils.mjs';
7+
export { insertAt, treeShakePreset } from './utils.mjs';

0 commit comments

Comments
 (0)