-
Notifications
You must be signed in to change notification settings - Fork 811
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
docs: Describe support for ESM #4876
Merged
pichlermarc
merged 17 commits into
open-telemetry:main
from
JamieDanielson:jamie.document-esm
Aug 27, 2024
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
e1db344
wip: adding notes about esm cjs support
JamieDanielson be4f9ee
add detail for initializing sdk
JamieDanielson e3891eb
rewrite instr hook and table
JamieDanielson 3848bc1
add more detail to TS, and ESM v CJS
JamieDanielson a4a9c10
add note about experimental loader
JamieDanielson ad96605
add dedicated doc for esm v cjs
JamieDanielson 9721191
refer to esm-vs-cjs doc in readmes
JamieDanielson 03c7149
format tables and fix typo
JamieDanielson 18c2ebe
Merge branch 'main' into jamie.document-esm
JamieDanielson d8ddcfc
Update experimental/packages/opentelemetry-instrumentation/README.md
JamieDanielson dc8b769
update links to esm doc
JamieDanielson ac44d4c
add another link to esm doc
JamieDanielson 94b88b3
format table
JamieDanielson 80a7440
remove note on bundler support
JamieDanielson c35db09
update based on feedback and testing
JamieDanielson 5d619ef
rename esm-vs-cjs to esm-support
JamieDanielson f3207f5
Update doc/esm-support.md
JamieDanielson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# ECMAScript Modules vs. CommonJS | ||
|
||
Node.js uses a different module loader for ECMAScript Modules (ESM) vs. CommonJS (CJS). | ||
To verify whether your application is ESM or CJS, refer to [Node.js docs for Determining Module System](https://nodejs.org/api/packages.html#determining-module-system). | ||
|
||
An `.mjs` extension or `type:module` in the built app's `package.json` indicates the app is ESM. | ||
|
||
**Much of OpenTelemetry JS documentation is written assuming the compiled application is run as CJS.** | ||
ESM support is ongoing; a few adjustments are needed for configuration and startup commands. | ||
|
||
For more explanation about CJS and ESM, see the [Node.js docs](https://nodejs.org/api/modules.html#enabling). | ||
|
||
## TypeScript | ||
|
||
Many TypeScript projects today are written using ESM syntax, regardless of how they are compiled. | ||
In the `tsconfig.json`, there is an option to compile to ESM or CJS. | ||
If the compiled code is ESM, those import statements will remain the same (e.g. `import { foo } from 'bar';`). | ||
If the compiled code is CJS, those import statements will become `require()` statements (e.g. `const { foo } = require('bar');`) | ||
|
||
## Initializing the SDK | ||
|
||
Instrumentation setup and configuration must be run before your application code. | ||
If the SDK is initialized in a separate file (recommended), ensure it is imported first in application startup, or use the `--require` or `--import` flag during startup to preload the module. | ||
|
||
For CJS, the `NODE_OPTIONS` for the startup command should include `--require ./telemetry.js`. | ||
|
||
For ESM, minimum Node.js version of `18.19.0` is required. | ||
The `NODE_OPTIONS` for the startup command should include `--import ./telemetry.js`. | ||
|
||
## Instrumentation Hook Required for ESM | ||
|
||
If your application is written in JavaScript as ESM, or compiled to ESM from TypeScript, then a loader hook is required to properly patch instrumentation. | ||
The custom hook for ESM instrumentation is `--experimental-loader=@opentelemetry/instrumentation/hook.mjs`. | ||
This flag must be passed to the `node` binary, which is often done as a startup command and/or in the `NODE_OPTIONS` environment variable. | ||
|
||
### Additional Notes on Experimental Loaders | ||
|
||
Though the OpenTelemetry loader currently relies on `import-in-the-middle`, direct usage of `import-in-the-middle/hook.mjs` may cease to work in the future. | ||
The only currently supported loader hook is `@opentelemetry/instrumentation/hook.mjs`. | ||
|
||
**Note:** Eventually the recommendation for how to setup OpenTelemetry for usage with ESM will change to no longer require `--experimental-loader=@opentelemetry/instrumentation/hook.mjs`. | ||
Instead the bootstrap code (in `./telemetry.js`) will use Node.js's newer `module.register(...)`. | ||
Refer to this [issue](https://github.com/open-telemetry/opentelemetry-js/issues/4933) for details. | ||
|
||
Because of ongoing issues with loaders running TypeScript code as ESM in development environments, results may vary. | ||
|
||
To use `ts-node` to run the uncompiled TypeScript code, the module must be CJS. | ||
To use `tsx` to run the uncompiled TypeScript code as ESM, the `--import` flag must be used. | ||
|
||
## Using the Zero Code Option with `auto-instrumentations-node` | ||
|
||
The `auto-instrumentations-node` package contains a `register` entry-point that can be used with `--require` or `--import` to setup and start the SDK easily, without application code changes. | ||
For ESM, the package also requires the usage of the loader hook. | ||
|
||
Startup command for CJS: | ||
|
||
```sh | ||
node --require @opentelemetry/auto-instrumentations-node/register app.js | ||
``` | ||
|
||
Startup command for ESM: | ||
|
||
```sh | ||
node --experimental-loader=@opentelemetry/instrumentation/hook.mjs --import @opentelemetry/auto-instrumentations-node/register app.js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Side note: It is also fine to use |
||
``` | ||
|
||
## Examples | ||
|
||
### Example Written in JavaScript as CJS | ||
|
||
```javascript | ||
/*telemetry.cjs*/ | ||
const { NodeSDK } = require('@opentelemetry/sdk-node'); | ||
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-node'); | ||
const { | ||
getNodeAutoInstrumentations, | ||
} = require('@opentelemetry/auto-instrumentations-node'); | ||
|
||
const sdk = new NodeSDK({ | ||
traceExporter: new ConsoleSpanExporter(), | ||
instrumentations: [getNodeAutoInstrumentations()], | ||
}); | ||
|
||
sdk.start(); | ||
``` | ||
|
||
Startup command: | ||
|
||
```sh | ||
node --require ./telemetry.cjs app.js | ||
``` | ||
|
||
### Example Written in JavaScript as ESM or TypeScript | ||
|
||
```typescript | ||
/*telemetry.ts | telemetry.mjs*/ | ||
import { NodeSDK } from '@opentelemetry/sdk-node'; | ||
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node'; | ||
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; | ||
|
||
const sdk = new NodeSDK({ | ||
traceExporter: new ConsoleSpanExporter(), | ||
instrumentations: [getNodeAutoInstrumentations()], | ||
}); | ||
|
||
sdk.start(); | ||
``` | ||
|
||
Startup command for compiled CJS: | ||
|
||
```sh | ||
node --require ./telemetry.js app.js | ||
``` | ||
|
||
Startup command for compiled ESM: | ||
|
||
```sh | ||
node --experimental-loader=@opentelemetry/instrumentation/hook.mjs --import ./telemetry.js app.js | ||
``` | ||
|
||
### ESM Options for Different Versions of Node.js | ||
|
||
The entire startup command should include the following `NODE_OPTIONS`: | ||
|
||
| Node.js Version | NODE_OPTIONS | | ||
| ----------------- | ----------------------------------------------------------------------------------------- | | ||
| 16.x | `--require ./telemetry.cjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` | | ||
| >=18.1.0 <18.19.0 | `--require ./telemetry.cjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` | | ||
| ^18.19.0 | `--import ./telemetry.mjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` | | ||
| 20.x | `--import ./telemetry.mjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` | | ||
| 22.x | `--import ./telemetry.mjs --experimental-loader=@opentelemetry/instrumentation/hook.mjs` | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The table cleanup is cool. This makes me realize this section is way out of date and a maintenance pain.
The "semconv" package is now a new category for the "OpenTelemetry is released as a set of distinct packages in 3 categories:" sentence at the start of this section.
Anyway... not for this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh actually I didn't mean to reformat anything in this doc. It must have auto-formatted when I added the first section and saved.