@@ -4,48 +4,33 @@ const instrumented = Object.keys(require('../datadog-instrumentations/src/helper
4
4
const builtins = new Set ( require ( 'module' ) . builtinModules )
5
5
const packages = new Set ( )
6
6
7
- // We don't want to handle any built-in packages via DCITM.
8
- // Those packages will still be handled via RITM.
9
- // Plust, attempting to instrument them will fail as they have no package.json file.
7
+ const DEBUG = ! ! process . env . DD_TRACE_DEBUG
8
+
9
+ // We don't want to handle any built-in packages via DCITM
10
+ // Those packages will still be handled via RITM
11
+ // Attempting to instrument them would fail as they have no package.json file
10
12
for ( let pkg of instrumented ) {
11
13
if ( builtins . has ( pkg ) ) continue
12
14
if ( pkg . startsWith ( 'node:' ) ) continue
13
15
packages . add ( pkg )
14
16
}
15
17
16
- // console.log(packages)
17
-
18
18
const DC_CHANNEL = 'dd-trace:bundledModuleLoadStart'
19
19
20
20
module . exports . name = 'datadog-esbuild'
21
21
22
22
module . exports . setup = function ( build ) {
23
23
build . onResolve ( { filter : / .* / } , args => {
24
24
const package_name = args . path
25
- // first call:
26
- /* args = {
27
- path: 'pg',
28
- importer: '/Users/thomas.hunter/Projects/esbuild-demo/app.js',
29
- namespace: 'file',
30
- resolveDir: '/Users/thomas.hunter/Projects/esbuild-demo',
31
- kind: 'require-call',
32
- pluginData: undefined
33
- } */
34
- // second call:
35
- /* args = {
36
- path: 'pg',
37
- importer: 'pg',
38
- namespace: 'datadog',
39
- resolveDir: '',
40
- kind: 'require-call',
41
- pluginData: undefined
42
- } */
25
+
43
26
if ( args . namespace === 'file' && packages . has ( package_name ) ) {
27
+ // The file namespace is used when requiring files from disk in userland
44
28
const pathToPackageJson = require . resolve ( `${ package_name } /package.json` , { paths : [ args . resolveDir ] } )
45
29
const pkg = require ( pathToPackageJson )
46
30
47
- console . log ( 'ONRESOLVE' , package_name , pkg . version , pathToPackageJson )
48
- // console.log(args)
31
+ if ( DEBUG ) {
32
+ console . log ( `resolve ${ package_name } @${ pkg . version } ` )
33
+ }
49
34
50
35
// https://esbuild.github.io/plugins/#on-resolve-arguments
51
36
return {
@@ -56,9 +41,9 @@ module.exports.setup = function(build) {
56
41
}
57
42
}
58
43
} else if ( args . namespace === 'datadog' ) {
59
- console . log ( 'ONRESOLVE DD' , package_name )
44
+ // The datadog namespace is used when requiring files that are injected during the onLoad stage
45
+ // see note in onLoad
60
46
61
- // @see note in onLoad
62
47
if ( package_name . startsWith ( 'node:' ) ) return
63
48
64
49
return {
@@ -69,29 +54,25 @@ module.exports.setup = function(build) {
69
54
} )
70
55
71
56
build . onLoad ( { filter : / .* / , namespace : NAMESPACE } , args => {
72
- /* args = {
73
- path: 'pg',
74
- namespace: 'datadog',
75
- suffix: '',
76
- pluginData: { version: '8.8.0' }
77
- } */
78
- console . log ( 'ONLOAD' , args . path , args . pluginData . version )
57
+ if ( DEBUG ) {
58
+ console . log ( `load ${ args . path } @${ args . pluginData . version } ` )
59
+ }
79
60
// TODO: relying on prefixing internal packages with `node:` in this intermediary module for now.
80
61
// If this causes an issue we'll need to update the logic for determining if a module is internal.
81
62
// Note that JSON.stringify adds double quotes for us. For perf gain we can simply add in quotes when we know it's safe.
82
63
let contents = `
83
- const dc = require('node:diagnostics_channel');
84
- const channel = dc.channel(${ JSON . stringify ( DC_CHANNEL + ':' + args . path ) } );
85
- const mod = require(${ JSON . stringify ( args . path ) } );
86
- const payload = {
64
+ const dc = require('node:diagnostics_channel');
65
+ const channel = dc.channel(${ JSON . stringify ( DC_CHANNEL + ':' + args . path ) } );
66
+ const mod = require(${ JSON . stringify ( args . path ) } );
67
+ const payload = {
87
68
module: mod,
88
69
path: ${ JSON . stringify ( args . path ) } ,
89
70
version: ${ JSON . stringify ( args . pluginData . version ) }
90
- };
91
- if (!channel.hasSubscribers) console.error('NO SUB ! ${ JSON . stringify ( DC_CHANNEL + ':' + args . path ) } ');
92
- channel.publish(payload); // subscriber may mutate payload
93
- module.exports = payload.module;
94
- module.exports.__DATADOG_VERSION = ${ JSON . stringify ( args . pluginData . version ) } ; // TODO: Unneccesary but cool
71
+ };
72
+ // if (!channel.hasSubscribers) console.error('missing subscriber ! ${ JSON . stringify ( DC_CHANNEL + ':' + args . path ) } ');
73
+ channel.publish(payload); // subscriber may mutate payload
74
+ module.exports = payload.module;
75
+ // module.exports.__DATADOG_VERSION = ${ JSON . stringify ( args . pluginData . version ) } ;
95
76
`
96
77
// https://esbuild.github.io/plugins/#on-load-results
97
78
return {
@@ -102,7 +83,7 @@ module.exports.setup = function(build) {
102
83
}
103
84
104
85
/**
105
- * This is just a convenience to expose a list of known externals to the application.
86
+ * This could be a convenience to expose a list of known externals to the application.
106
87
* Devs are free to use this list, ignore it, or merge it with their application-specific list.
107
88
* TODO: Sadly, esbuild does not allow unanticipated keys on the exported object.
108
89
* Could do `{ plugin: { name, setup }, knownExternals }`
0 commit comments