Skip to content

Commit df99272

Browse files
committed
Activate ESM loader hook of the "import-in-the-middle" library for ES (EcmaScript) based user handlers
1 parent cf82ba1 commit df99272

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

nodejs/packages/layer/scripts/otel-handler

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
set -ef -o pipefail
44

5-
export NODE_OPTIONS="${NODE_OPTIONS} --require /opt/wrapper.js"
5+
export NODE_OPTIONS="${NODE_OPTIONS} --import /opt/loader.mjs --require /opt/wrapper.js"
66

77
if [[ $OTEL_RESOURCE_ATTRIBUTES != *"service.name="* ]]; then
88
export OTEL_RESOURCE_ATTRIBUTES="service.name=${AWS_LAMBDA_FUNCTION_NAME},${OTEL_RESOURCE_ATTRIBUTES}"
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { register } from 'module';
2+
import * as path from 'path';
3+
import * as fs from 'fs';
4+
5+
function _hasFolderPackageJsonTypeModule(folder) {
6+
if (folder.endsWith('/node_modules')) {
7+
return false;
8+
}
9+
let pj = path.join(folder, '/package.json');
10+
if (fs.existsSync(pj)) {
11+
try {
12+
let pkg = JSON.parse(fs.readFileSync(pj).toString());
13+
if (pkg) {
14+
if (pkg.type === 'module') {
15+
return true;
16+
} else {
17+
return false;
18+
}
19+
}
20+
} catch (e) {
21+
console.warn(`${pj} cannot be read, it will be ignored for ES module detection purposes.`, e);
22+
return false;
23+
}
24+
}
25+
if (folder === '/') {
26+
return false;
27+
}
28+
return _hasFolderPackageJsonTypeModule(path.resolve(folder, '..'));
29+
}
30+
31+
function _hasPackageJsonTypeModule(file) {
32+
let jsPath = file + '.js';
33+
if (fs.existsSync(jsPath)) {
34+
return _hasFolderPackageJsonTypeModule(path.resolve(path.dirname(jsPath)));
35+
}
36+
return false;
37+
}
38+
39+
function _resolveHandlerFileName() {
40+
const taskRoot = process.env.LAMBDA_TASK_ROOT;
41+
const handlerDef = process.env._HANDLER;
42+
const handler = path.basename(handlerDef);
43+
const moduleRoot = handlerDef.substr(0, handlerDef.length - handler.length);
44+
const [module, _] = handler.split('.', 2);
45+
return path.resolve(taskRoot, moduleRoot, module);
46+
}
47+
48+
function _isHandlerAnESModule() {
49+
const handlerFileName = _resolveHandlerFileName();
50+
if (fs.existsSync(handlerFileName + '.mjs')) {
51+
return true;
52+
} else if (fs.existsSync(handlerFileName + '.cjs')) {
53+
return false;
54+
} else {
55+
return _hasPackageJsonTypeModule(handlerFileName);
56+
}
57+
}
58+
59+
if (_isHandlerAnESModule()) {
60+
/*
61+
We could activate ESM loader hook of the "import-in-the-middle" library,
62+
- by "--loader=import-in-the-middle/hook.mjs" Node CLI option, but "--loader" option has been deprecated
63+
- or by "--import=import-in-the-middle/hook.mjs" Node CLI option, but in this case,
64+
there will always be "import-in-the-middle" hook initialization overhead even for non-ESM (CommonJS) modules
65+
66+
Hence, instead, we initialize "import-in-the-middle" hook only for ES (EcmaScript) based user handlers
67+
to prevent redundant "import-in-the-middle" hook initialization overhead during coldstart
68+
of the CommonJS based user handlers.
69+
*/
70+
register('import-in-the-middle/hook.mjs', import.meta.url);
71+
}

0 commit comments

Comments
 (0)