Skip to content

Conversation

@BenoitZugmeyer
Copy link
Member

@BenoitZugmeyer BenoitZugmeyer commented Oct 31, 2025

Motivation

I'm about to introduce a bunch of new packages. I want to reduce the amount of boilerplate we need to maintain within each package.

Changes

Introduce a new "build-package" script to unify how we build all packages. It supports two options, --modules and --bundle to either build modules or bundles (or both), following package needs.

The npm-run-all dependency has been removed. Packages are not built in parallel anymore, but that doesn't seem to impact the overall build time (at least on my machine):

Before:

yarn build  21.685s
yarn build:bundle  10.414s

After:

yarn build  21.123s
yarn build:bundle 10.409s

Test instructions

Run yarn build, check if everything is correctly built.
Check if yarn dev is still working.

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.

@datadog-official
Copy link

datadog-official bot commented Oct 31, 2025

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage
Patch Coverage: 100.00%
Total Coverage: 92.63% (+0.00%)

View detailed report

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 8722954 | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@BenoitZugmeyer BenoitZugmeyer force-pushed the benoit/reduce-build-boilerplate branch 2 times, most recently from b74ccc4 to cc7a0e5 Compare October 31, 2025 11:38
@BenoitZugmeyer BenoitZugmeyer force-pushed the benoit/reduce-build-boilerplate branch from cc7a0e5 to b3576cf Compare November 4, 2025 14:59
@cit-pr-commenter
Copy link

cit-pr-commenter bot commented Nov 4, 2025

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 163.88 KiB 163.88 KiB 0 B 0.00%
Rum Profiler 4.84 KiB 4.84 KiB 0 B 0.00%
Rum Recorder 19.78 KiB 19.78 KiB 0 B 0.00%
Logs 56.35 KiB 56.35 KiB 0 B 0.00%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 121.13 KiB 121.13 KiB 0 B 0.00%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance

Pending...

🧠 Memory Performance

Pending...

🔗 RealWorld

@BenoitZugmeyer BenoitZugmeyer force-pushed the benoit/reduce-build-boilerplate branch from b3576cf to de520ca Compare November 4, 2025 16:47
@BenoitZugmeyer BenoitZugmeyer force-pushed the benoit/reduce-build-boilerplate branch from 5ae0b2f to 2be9686 Compare November 4, 2025 17:22
// [1]: Quoting Lerna doc: "Lerna always uses npm to publish packages."
// https://lerna.js.org/docs/features/version-and-publish#from-package
const output = command`npm pack --dry-run --json`.withCurrentWorkingDirectory(packagePath).run()
const output = command`npm pack --ignore-scripts --dry-run --json`.withCurrentWorkingDirectory(packagePath).run()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this is because npm pack runs the prepack npm script in the react package. Previously this script didn't output anything, but now it prints "Building modules...", breaking the JSON output.

Ignoring scripts is fine here, since the check-packages command is run after the packages are freshly built, so no need to build the react plugin again.

Comment on lines 81 to 123
const parsed = ts.parseJsonConfigFileContent(
{
extends: '../../tsconfig.base.json',
compilerOptions: {
baseUrl: '.',
declaration: true,
allowJs: true,
module,
rootDir: './src/',
outDir,
},
include: ['./src'],
exclude: ['./src/**/*.spec.*', './src/**/*.specHelper.*'],
},
ts.sys,
process.cwd(),
undefined,
'tsconfig.json' // just used in messages
)

const host = ts.createCompilerHost(parsed.options)
const program = ts.createProgram({
rootNames: parsed.fileNames,
options: parsed.options,
host,
})

const emitResult = program.emit()
const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics)

if (diagnostics.length) {
const formatHost: ts.FormatDiagnosticsHost = {
getCanonicalFileName: (f) => f,
// eslint-disable-next-line @typescript-eslint/unbound-method
getCurrentDirectory: ts.sys.getCurrentDirectory,
getNewLine: () => ts.sys.newLine,
}
console.error(ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost))
}

if (emitResult.emitSkipped) {
throw new Error('Failed to build package')
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love this TypeScript code, but at the same time I didn't find a better way to invoke TypeScript with a dynamic configuration (maybe with a temporary file that we put somewhere and feed to tsc... but I'm not sure it's better).

As I'm mentioning in the comment above, I hope we can move on from TypeScript for building packages at some point.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me it's fine but maybe you could clarify what it does with comments or split it into smaller functions with clear names?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 3b108a1

webpackBase({
mode: 'development',
entry: `${packagePath}/src/entries/main.ts`,
filename: packageName === 'worker' ? 'worker.js' : `datadog-${packageName}.js`,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • There is a little bit of duplication between the build-package.ts and dev-server.ts. I believe this is acceptable as long as it's only a couple of lines.

  • I don't love this filename exception for worker.js. Maybe we can unify filenames here, and always generate ${packageName}.js (ex: rum.js, logs.js) or always datadog-${packageName}.js (ex: datadog-worker.js). Those paths are currently used in e2e tests and the devtools extension, so that's not as straightforward as it might seem. I think this is fine for now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, having a more consistent naming would help having more generic scripts without having to hardcode names. let's keep that in mind, maybe for a mob session?

@BenoitZugmeyer BenoitZugmeyer marked this pull request as ready for review November 4, 2025 17:33
@BenoitZugmeyer BenoitZugmeyer requested a review from a team as a code owner November 4, 2025 17:33
webpackBase({
mode: 'development',
entry: `${packagePath}/src/entries/main.ts`,
filename: packageName === 'worker' ? 'worker.js' : `datadog-${packageName}.js`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, having a more consistent naming would help having more generic scripts without having to hardcode names. let's keep that in mind, maybe for a mob session?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants