Skip to content

Commit

Permalink
fix: esbuildBinaryPath not working with Code, not available for `…
Browse files Browse the repository at this point in the history
…InlineCode` (#210)

Fixes #203
  • Loading branch information
mrgrain authored Aug 13, 2022
1 parent a7d14e7 commit dc2609b
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 26 deletions.
14 changes: 14 additions & 0 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions src/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ export class EsbuildAsset<Props extends AssetProps> extends S3Asset {
) {
const {
assetHash,
copyDir,
buildOptions: options = {},
buildFn,
} = props;
const entryPoints: string[] | Record<string, string> =
typeof props.entryPoints === 'string' ? [props.entryPoints] : props.entryPoints;
Expand Down Expand Up @@ -110,9 +108,8 @@ export class EsbuildAsset<Props extends AssetProps> extends S3Asset {
bundling: new EsbuildBundler(
relativeEntryPoints,
{
...props,
buildOptions,
copyDir,
buildFn,
},
),
});
Expand Down
21 changes: 3 additions & 18 deletions src/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
ILocalBundling,
} from 'aws-cdk-lib';
import { BuildFailure, BuildOptions, BuildResult } from './esbuild-types';
import { buildSync } from './esbuild-wrapper';
import { buildSync, wrapWithEsbuildBinaryPath } from './esbuild-wrapper';
import { printBuildMessages } from './formatMessages';

/**
Expand Down Expand Up @@ -152,9 +152,6 @@ export class EsbuildBundler {
if (props?.buildOptions?.outfile && props?.buildOptions?.outdir) {
throw new Error('Cannot use both "outfile" and "outdir"');
}

const { buildFn = buildSync } = this.props;

this.local = {
tryBundle: (outputDir: string, _options: BundlingOptions): boolean => {

Expand All @@ -178,13 +175,9 @@ export class EsbuildBundler {
});
}

const originalEsbuildBinaryPath = process.env.ESBUILD_BINARY_PATH;
if (this.props.esbuildBinaryPath) {
process.env.ESBUILD_BINARY_PATH = this.props.esbuildBinaryPath;
}

try {
const buildResult: BuildResult = buildFn({
const { buildFn = buildSync } = this.props;
const buildResult: BuildResult = wrapWithEsbuildBinaryPath(buildFn, this.props.esbuildBinaryPath)({
entryPoints,
...(this.props?.buildOptions || {}),
...this.getOutputOptions(outputDir, { normalize, join }),
Expand All @@ -195,14 +188,6 @@ export class EsbuildBundler {
printBuildMessages(error as BuildFailure, { prefix: 'Build ' });
}

/**
* only reset `ESBUILD_BINARY_PATH` if it was explicitly set via the construct props
* since `esbuild` itself sometimes sets it (eg. when running in yarn 2 plug&play)
*/
if (this.props.esbuildBinaryPath) {
process.env.ESBUILD_BINARY_PATH = originalEsbuildBinaryPath;
}

return true;
},
};
Expand Down
25 changes: 25 additions & 0 deletions src/esbuild-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,28 @@ function esbuild() {
export const buildSync = esbuild().buildSync;
export const formatMessagesSync = esbuild().formatMessagesSync;
export const transformSync = esbuild().transformSync;

export function wrapWithEsbuildBinaryPath<T extends CallableFunction>(fn: T, esbuildBinaryPath?: string) {
if (!esbuildBinaryPath) {
return fn;
}

return (...args: unknown[]) => {
const originalEsbuildBinaryPath = process.env.ESBUILD_BINARY_PATH;
if (esbuildBinaryPath) {
process.env.ESBUILD_BINARY_PATH = esbuildBinaryPath;
}

const result = fn(...args);

/**
* only reset `ESBUILD_BINARY_PATH` if it was explicitly set via the construct props
* since `esbuild` itself sometimes sets it (eg. when running in yarn 2 plug&play)
*/
if (esbuildBinaryPath) {
process.env.ESBUILD_BINARY_PATH = originalEsbuildBinaryPath;
}

return result;
};
}
29 changes: 25 additions & 4 deletions src/inline-code.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { InlineCode } from 'aws-cdk-lib/aws-lambda';
import { TransformOptions, Loader, TransformFailure } from './esbuild-types';
import { transformSync } from './esbuild-wrapper';
import { transformSync, wrapWithEsbuildBinaryPath } from './esbuild-wrapper';
import { printBuildMessages } from './formatMessages';

/**
Expand All @@ -27,6 +27,15 @@ export interface TransformerProps {
* @default esbuild.transformSync
*/
readonly transformFn?: any;

/**
* Path to the binary used by esbuild.
*
* This is the same as setting the ESBUILD_BINARY_PATH environment variable.
*
* @stability experimental
*/
readonly esbuildBinaryPath?: string;
}

abstract class BaseInlineCode extends InlineCode {
Expand All @@ -35,10 +44,14 @@ abstract class BaseInlineCode extends InlineCode {
props: TransformerProps,
) {

const { transformFn = transformSync, transformOptions = {} } = props;
const {
transformFn = transformSync,
transformOptions = {},
esbuildBinaryPath,
} = props;

try {
const transformedCode = transformFn(code, {
const transformedCode = wrapWithEsbuildBinaryPath(transformFn, esbuildBinaryPath)(code, {
...transformOptions,
});
printBuildMessages(transformedCode, { prefix: 'Transform ' });
Expand All @@ -53,7 +66,15 @@ abstract class BaseInlineCode extends InlineCode {
}

function instanceOfTransformerProps(object: any): object is TransformerProps {
return 'transformOptions' in object || 'transformFn' in object;
return [
'transformOptions',
'transformFn',
'esbuildBinaryPath',
].reduce(
(isTransformerProps: boolean, propToCheck: string): boolean =>
(isTransformerProps || (propToCheck in object)),
false,
);
}

function transformerProps(loader: Loader, props?: TransformerProps | TransformOptions): TransformerProps {
Expand Down
31 changes: 31 additions & 0 deletions test/code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Stack } from 'aws-cdk-lib';
import { Function, Runtime as LambdaRuntime } from 'aws-cdk-lib/aws-lambda';
import { mocked } from 'jest-mock';
import { JavaScriptCode, TypeScriptCode } from '../src/code';
import { BuildOptions } from '../src/esbuild-types';
import { buildSync } from '../src/esbuild-wrapper';

describe('code', () => {
Expand Down Expand Up @@ -145,6 +146,36 @@ describe('code', () => {
});
});


describe('given a custom esbuildBinaryPath', () => {
it('should set the ESBUILD_BINARY_PATH env variable', () => {
const mockLogger = jest.fn();
const customBuild = (options: BuildOptions) => {
mockLogger(process.env.ESBUILD_BINARY_PATH);
return buildSync(options);
};

expect(() => {
const stack = new Stack();

const code = new TypeScriptCode('fixtures/handlers/ts-handler.ts', {
buildOptions: { absWorkingDir: resolve(__dirname) },
buildFn: customBuild,
esbuildBinaryPath: 'dummy-binary',
});

new Function(stack, 'MyFunction', {
runtime: LambdaRuntime.NODEJS_14_X,
handler: 'index.handler',
code,
});
}).not.toThrow();

expect(mockLogger).toHaveBeenCalledTimes(1);
expect(mockLogger).toHaveBeenCalledWith('dummy-binary');
});
});

describe('AWS Lambda', () => {
describe('TypeScriptCode can be used in Lambda Function', () => {
it('should not throw', () => {
Expand Down
22 changes: 22 additions & 0 deletions test/inline-code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,26 @@ describe('using transformerProps', () => {
);
});
});

describe('given a custom esbuildBinaryPath', () => {
it('should set the ESBUILD_BINARY_PATH env variable', () => {
const mockLogger = jest.fn();
const customTransform = () => {
mockLogger(process.env.ESBUILD_BINARY_PATH);
return {
code: 'console.log("test");',
map: '',
warnings: [],
};
};

new InlineTypeScriptCode('let x: number = 1', {
transformFn: customTransform,
esbuildBinaryPath: 'dummy-binary',
});

expect(mockLogger).toHaveBeenCalledTimes(1);
expect(mockLogger).toHaveBeenCalledWith('dummy-binary');
});
});
});

0 comments on commit dc2609b

Please sign in to comment.