Skip to content

Commit 35778f9

Browse files
feat: add custom esbuild entrypoint in function definitions (#546)
* feat: add custom esbuild entrypoint in function definitions * docs: change quotes
1 parent 6deddd2 commit 35778f9

File tree

4 files changed

+39
-5
lines changed

4 files changed

+39
-5
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,16 @@ module.exports = (serverless) => {
282282

283283
As long as the plugin is properly installed, all regular Serverless operations `sls package`, `sls deploy`, `sls deploy function`, `sls invoke local`, `sls offline` will automatically compile using `serverless-esbuild`.
284284

285+
### Specify a custom entrypoint for a function
286+
287+
You can specify a custom entrypoint for ESBuild by specifying the `esbuildEntrypoint` field in your function definition.
288+
```typescript
289+
export const myLambdaFunction = {
290+
handler: '/opt/nodejs/node_modules/my_custom_extension/handler.handler',
291+
esbuildEntrypoint: './handler.main',
292+
};
293+
```
294+
285295
### Serverless Offline
286296

287297
The plugin integrates very well with [serverless-offline](https://github.com/dherault/serverless-offline) to

src/helper.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,16 @@ export function extractFunctionEntries(
6262
return !(functions[functionAlias] as EsbuildFunctionDefinitionHandler).skipEsbuild;
6363
})
6464
.map((functionAlias) => {
65-
const func = functions[functionAlias];
65+
const func = functions[functionAlias] as EsbuildFunctionDefinitionHandler;
6666
assert(func, `${functionAlias} not found in functions`);
6767

68-
const { handler } = func;
69-
const fnName = path.extname(handler);
70-
const fnNameLastAppearanceIndex = handler.lastIndexOf(fnName);
68+
const { handler, esbuildEntrypoint } = func;
69+
const entrypoint = esbuildEntrypoint || handler;
70+
71+
const fnName = path.extname(entrypoint);
72+
const fnNameLastAppearanceIndex = entrypoint.lastIndexOf(fnName);
7173
// replace only last instance to allow the same name for file and handler
72-
const fileName = handler.substring(0, fnNameLastAppearanceIndex);
74+
const fileName = entrypoint.substring(0, fnNameLastAppearanceIndex);
7375

7476
const extensions = resolveExtensions ?? DEFAULT_EXTENSIONS;
7577

src/tests/helper.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,27 @@ describe('extractFunctionEntries', () => {
211211
]);
212212
});
213213

214+
it('should use esbuildEntrypoint in priority', () => {
215+
jest.mocked(fs.existsSync).mockReturnValue(true);
216+
const functionDefinitions = {
217+
function1: {
218+
events: [],
219+
handler: '/opt/extension/my_custom_handler',
220+
esbuildEntrypoint: 'file1.handler',
221+
},
222+
};
223+
224+
const fileNames = extractFunctionEntries(cwd, 'aws', functionDefinitions);
225+
226+
expect(fileNames).toStrictEqual([
227+
{
228+
entry: 'file1.ts',
229+
func: functionDefinitions.function1,
230+
functionAlias: 'function1',
231+
},
232+
]);
233+
});
234+
214235
it('should throw an error if the handlers reference a file which does not exist', () => {
215236
jest.mocked(fs.existsSync).mockReturnValue(false);
216237
const functionDefinitions = {

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export interface Configuration extends EsbuildOptions {
5555
export interface EsbuildFunctionDefinitionHandler extends Serverless.FunctionDefinitionHandler {
5656
disposeContext?: boolean;
5757
skipEsbuild: boolean;
58+
esbuildEntrypoint?: string;
5859
}
5960

6061
export interface FunctionEntry {

0 commit comments

Comments
 (0)