Skip to content

Commit

Permalink
feat: add custom esbuild entrypoint in function definitions (#546)
Browse files Browse the repository at this point in the history
* feat: add custom esbuild entrypoint in function definitions

* docs: change quotes
  • Loading branch information
alexandre-snr committed Sep 24, 2024
1 parent 6deddd2 commit 35778f9
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,16 @@ module.exports = (serverless) => {

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`.

### Specify a custom entrypoint for a function

You can specify a custom entrypoint for ESBuild by specifying the `esbuildEntrypoint` field in your function definition.
```typescript
export const myLambdaFunction = {
handler: '/opt/nodejs/node_modules/my_custom_extension/handler.handler',
esbuildEntrypoint: './handler.main',
};
```

### Serverless Offline

The plugin integrates very well with [serverless-offline](https://github.com/dherault/serverless-offline) to
Expand Down
12 changes: 7 additions & 5 deletions src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,16 @@ export function extractFunctionEntries(
return !(functions[functionAlias] as EsbuildFunctionDefinitionHandler).skipEsbuild;
})
.map((functionAlias) => {
const func = functions[functionAlias];
const func = functions[functionAlias] as EsbuildFunctionDefinitionHandler;
assert(func, `${functionAlias} not found in functions`);

const { handler } = func;
const fnName = path.extname(handler);
const fnNameLastAppearanceIndex = handler.lastIndexOf(fnName);
const { handler, esbuildEntrypoint } = func;
const entrypoint = esbuildEntrypoint || handler;

const fnName = path.extname(entrypoint);
const fnNameLastAppearanceIndex = entrypoint.lastIndexOf(fnName);
// replace only last instance to allow the same name for file and handler
const fileName = handler.substring(0, fnNameLastAppearanceIndex);
const fileName = entrypoint.substring(0, fnNameLastAppearanceIndex);

const extensions = resolveExtensions ?? DEFAULT_EXTENSIONS;

Expand Down
21 changes: 21 additions & 0 deletions src/tests/helper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,27 @@ describe('extractFunctionEntries', () => {
]);
});

it('should use esbuildEntrypoint in priority', () => {
jest.mocked(fs.existsSync).mockReturnValue(true);
const functionDefinitions = {
function1: {
events: [],
handler: '/opt/extension/my_custom_handler',
esbuildEntrypoint: 'file1.handler',
},
};

const fileNames = extractFunctionEntries(cwd, 'aws', functionDefinitions);

expect(fileNames).toStrictEqual([
{
entry: 'file1.ts',
func: functionDefinitions.function1,
functionAlias: 'function1',
},
]);
});

it('should throw an error if the handlers reference a file which does not exist', () => {
jest.mocked(fs.existsSync).mockReturnValue(false);
const functionDefinitions = {
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface Configuration extends EsbuildOptions {
export interface EsbuildFunctionDefinitionHandler extends Serverless.FunctionDefinitionHandler {
disposeContext?: boolean;
skipEsbuild: boolean;
esbuildEntrypoint?: string;
}

export interface FunctionEntry {
Expand Down

0 comments on commit 35778f9

Please sign in to comment.