aplicationinsights package incompatibilities with ESM
- Package Name: applicationinsights
- Package Version: 3.1.0
- Operating system: Doesn't matter
- [x] nodejs
- version: 20
- [ ] browser
- name/version:
- [ ] typescript
- version:
Describe the bug
applicationinsights doesn't work properly in ESM environment
This issue is possibly a duplicate of https://github.com/microsoft/ApplicationInsights-node.js/issues/1205 but with more details and workaround.
To Reproduce Steps to reproduce the behavior:
- Set
"type": "module",inpackage.json - Add
import { setup, defaultClient } from 'applicationinsights'; setup().start(); console.log(defaultClient); - Run the app and check the console output,
defaultClientwould be undefined.
Expected behavior
defaultClient should be fulfilled
Additional context This happened because of the differences how native ESM and transpiled to CJS modules works.
If you look to the entry point of the 'applicationinsights' package you will see:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.dispose =
exports.TelemetryClient =
exports.DistributedTracingModes =
exports.Contracts = exports.defaultClient =
exports.Configuration = exports.wrapWithCorrelationContext =
exports.startOperation = exports.getCorrelationContext = exports.start = exports.setup = void 0;
var applicationinsights_1 = require("./src/shim/applicationinsights");
Object.defineProperty(exports, "setup", { enumerable: true, get: function () { return applicationinsights_1.setup; } });
Object.defineProperty(exports, "defaultClient", { enumerable: true, get: function () { return applicationinsights_1.defaultClient; } });
// ... other exports
When this package would be requested in CJS context, those getters would be invoked only when user's code will actually access them, but in ESM context, ESM loader enumerate all properties which are exported from the package and save result internally, so getter for defaultClient is executed only once and before this client ever initialized.
There is no simple way to fix this, other than don't use late-binding at all. So instead of defaultClient expose a function getDefaultClient()
To workaround the issue, i created a cjs file which is called from my ESM modules with the following content:
// telemetry.cjs
const applicationinsights = require('applicationinsights');
applicationinsights.setup().start();
module.exports = {
telemetryClient: applicationinsights.defaultClient
}
@thekip
I also found that applicationinsights v3 doesn't work well with ESM.
For your issue, I found the following code works for me, the defaultClient will not be undefined.
import applicationInsights from "applicationinsights";
applicationInsights.setup(connectionString)
.setSendLiveMetrics(true)
.start();
console.log(applicationInsights.defaultClient === undefined) // defaultClient won't be undefined
applicationInsights.defaultClient.trackEvent({name: "TestEvent"}); // this line works but it will give me some warning/error log
But I will get the following log which is caused by the trackEvent call:
Accessing resource attributes before async attributes settled []
I can get the custom event in the application insights, but this log seems a bug to me and it's quite annoying.
I am using version 3.2.2.
@zhiyuanliang-ms Unfortunately that log is something that OpenTelemetry throws when we initialize before letting the resource detector's attempt to determine if the SDK is running in a VM. I'll look into how to resolve that log, however it should have no impact on your ability to receive telemetry.
@thekip Solution to this issue presented by the OTel community is in the discussion on #1375 just FYI in case you run into issues with automatically collecting telemetry from HTTP, DBs, etc.
@timofei-iatsenko RE:
To workaround the issue, i created a cjs file which is called from my ESM modules with the following content:
What syntax did you use to call the cjs file from your ESM module?
I assume the regular import statement, there should be no issue calling CJS from ESM files.
Any other solution for defaultClient undefined? I'm not able to use CJS with Vite
@vanessateixeira-br I'm not aware of any workaround at this time, but it may make sense to reach out to the OpenTelemetry-JS community if you're having specific issues with .cjs files as this usage of them is their official workaround.
Seeing as we're dependent on OpenTelemetry and they have this restriction on how ESM is handled (and a community sanctioned solution), I'm closing this issue for now and will update if any updates come from the OpenTelemetry-JS community.