Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions lib/plugins/aws/invoke-local/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -842,10 +842,18 @@ class AwsInvokeLocal {
pathToHandler = `${pathToHandler}.cjs`;
try {
return require(pathToHandler);
} catch (innerError) {
// Throw original error if still "MODULE_NOT_FOUND", as not finding module with `.cjs` might be confusing
if (innerError.code !== 'MODULE_NOT_FOUND') {
throw innerError;
} catch (cjsInnerError) {
if (cjsInnerError.code !== 'MODULE_NOT_FOUND') {
throw cjsInnerError;
}
// Attempt to load `.mjs` extension
try {
return await import(`file:///${modulePath}.mjs`);
} catch (mjsInnerError) {
if (mjsInnerError.code !== 'MODULE_NOT_FOUND') {
throw mjsInnerError;
// Throw original error if still "MODULE_NOT_FOUND", as not finding module with `.cjs` might be confusing
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@
"no-console": "off"
}
},
{
"files": [
"test/fixtures/programmatic/invocation/cjs/**"
],
"parserOptions": {
"sourceType": "module",
"allowImportExportEverywhere": true
}
},
{
"files": [
"test/fixtures/programmatic/plugin/local-esm-plugin/**",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const handler = async (event, context) => {
if (event && event.shouldFail) throw new Error('Failed on request');
return {
statusCode: 200,
body: JSON.stringify({
message: 'Invoked',
event,
clientContext: context.clientContext,
env: process.env,
}),
};
};

export default handler;
3 changes: 3 additions & 0 deletions test/fixtures/programmatic/invocation/cjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const handler = async (event, context) => {
if (event && event.shouldFail) throw new Error('Failed on request');
return {
statusCode: 200,
body: JSON.stringify({
message: 'Invoked',
event,
clientContext: context.clientContext,
env: process.env,
}),
};
};

export default handler;
4 changes: 4 additions & 0 deletions test/fixtures/programmatic/invocation/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ functions:
handler: async-cjs.handler
asyncEsm:
handler: esm/async-esm.handler
asyncEsmMjsInModulePackageType:
handler: esm/async-esm-mjs-in-module-package-type.handler
asyncEsmMjsInCommonjsPackageType:
handler: cjs/async-esm-mjs-in-commonjs-package-type.handler
contextDone:
handler: context-done.handler
contextSucceed:
Expand Down
18 changes: 18 additions & 0 deletions test/unit/lib/plugins/aws/invoke-local/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,24 @@ describe('test/unit/lib/plugins/aws/invokeLocal/index.test.js', () => {
options: { function: 'asyncEsm' },
});

expect(output).to.include('Invoked');
});
it('should support loading handlers that are ES modules with `.mjs` extension in packages of `module` type', async () => {
const { output } = await runServerless({
fixture: 'invocation',
command: 'invoke local',
options: { function: 'asyncEsmMjsInModulePackageType' },
});

expect(output).to.include('Invoked');
});
it('should support loading handlers that are ES modules with `.mjs` extension in packages of `commonjs` type', async () => {
const { output } = await runServerless({
fixture: 'invocation',
command: 'invoke local',
options: { function: 'asyncEsmMjsInCommonjsPackageType' },
});

expect(output).to.include('Invoked');
});
});
Expand Down