Skip to content

Commit

Permalink
Merge branch 'master' into huijbers/dep-cycle
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Jan 28, 2022
2 parents e9dee61 + 7ac7221 commit 6dd81c7
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 85 deletions.
30 changes: 8 additions & 22 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as cdk from '@aws-cdk/core';
import { PackageInstallation } from './package-installation';
import { PackageManager } from './package-manager';
import { BundlingOptions, OutputFormat, SourceMapMode } from './types';
import { exec, extractDependencies, findUp } from './util';
import { exec, extractDependencies, findUp, getTsconfigCompilerOptions } from './util';

const ESBUILD_MAJOR_VERSION = '0';

Expand Down Expand Up @@ -68,13 +68,8 @@ export class Bundling implements cdk.BundlingOptions {
this.tscInstallation = undefined;
}

public static clearTscCompilationCache(): void {
this.tscCompiled = false;
}

private static esbuildInstallation?: PackageInstallation;
private static tscInstallation?: PackageInstallation;
private static tscCompiled = false

// Core bundling options
public readonly image: cdk.DockerImage;
Expand Down Expand Up @@ -156,26 +151,17 @@ export class Bundling implements cdk.BundlingOptions {

private createBundlingCommand(options: BundlingCommandOptions): string {
const pathJoin = osPathJoin(options.osPlatform);
let tscCommand: string = '';
let relativeEntryPath = this.relativeEntryPath;
let relativeEntryPath = pathJoin(options.inputDir, this.relativeEntryPath);
let tscCommand = '';

if (this.props.preCompilation) {

let tsconfig = this.relativeTsconfigPath;
const tsconfig = this.props.tsconfig ?? findUp('tsconfig.json', path.dirname(this.props.entry));
if (!tsconfig) {
const findConfig = findUp('tsconfig.json', path.dirname(this.props.entry));
if (!findConfig) {
throw new Error('Cannot find a tsconfig.json, please specify the prop: tsconfig');
}
tsconfig = path.relative(this.projectRoot, findConfig);
throw new Error('Cannot find a `tsconfig.json` but `preCompilation` is set to `true`, please specify it via `tsconfig`');
}

const compilerOptions = getTsconfigCompilerOptions(tsconfig);
tscCommand = `${options.tscRunner} "${relativeEntryPath}" ${compilerOptions}`;
relativeEntryPath = relativeEntryPath.replace(/\.ts(x?)$/, '.js$1');
if (!Bundling.tscCompiled) {
// Intentionally Setting rootDir and outDir, so that the compiled js file always end up next ts file.
tscCommand = `${options.tscRunner} --project ${pathJoin(options.inputDir, tsconfig)} --rootDir ./ --outDir ./`;
Bundling.tscCompiled = true;
}
}

const loaders = Object.entries(this.props.loader ?? {});
Expand All @@ -193,7 +179,7 @@ export class Bundling implements cdk.BundlingOptions {
const outFile = this.props.format === OutputFormat.ESM ? 'index.mjs' : 'index.js';
const esbuildCommand: string[] = [
options.esbuildRunner,
'--bundle', `"${pathJoin(options.inputDir, relativeEntryPath)}"`,
'--bundle', `"${relativeEntryPath}"`,
`--target=${this.props.target ?? toTarget(this.props.runtime)}`,
'--platform=node',
...this.props.format ? [`--format=${this.props.format}`] : [],
Expand Down
62 changes: 62 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,65 @@ export function extractDependencies(pkgPath: string, modules: string[]): { [key:

return dependencies;
}

export function getTsconfigCompilerOptions(tsconfigPath: string): string {
const compilerOptions = extractTsConfig(tsconfigPath);
const excludedCompilerOptions = [
'composite',
'tsBuildInfoFile',
];

const options: Record<string, any> = {
...compilerOptions,
// Overrides
incremental: false,
// Intentionally Setting rootDir and outDir, so that the compiled js file always end up next to .ts file.
rootDir: './',
outDir: './',
};

let compilerOptionsString = '';
Object.keys(options).forEach((key: string) => {

if (excludedCompilerOptions.includes(key)) {
return;
}

const value = options[key];
const option = '--' + key;
const type = typeof value;

if (type === 'boolean') {
if (value) {
compilerOptionsString += option + ' ';
}
} else if (type === 'string') {
compilerOptionsString += option + ' ' + value + ' ';
} else if (type === 'object') {
if (Array.isArray(value)) {
compilerOptionsString += option + ' ' + value.join(',') + ' ';
}
} else {
throw new Error(`Missing support for compilerOption: [${key}]: { ${type}, ${value}} \n`);
}
});

return compilerOptionsString.trim();
}


function extractTsConfig(tsconfigPath: string, previousCompilerOptions?: Record<string, any>): Record<string, any> | undefined {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { extends: extendedConfig, compilerOptions } = require(tsconfigPath);
const updatedCompilerOptions = {
...(previousCompilerOptions ?? {}),
...compilerOptions,
};
if (extendedConfig) {
return extractTsConfig(
path.resolve(tsconfigPath.replace(/[^\/]+$/, ''), extendedConfig),
updatedCompilerOptions,
);
}
return updatedCompilerOptions;
}
69 changes: 7 additions & 62 deletions packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ beforeEach(() => {
jest.resetAllMocks();
jest.restoreAllMocks();
Bundling.clearEsbuildInstallationCache();
Bundling.clearTscInstallationCache();

jest.spyOn(Code, 'fromAsset');

Expand Down Expand Up @@ -574,90 +573,36 @@ test('esbuild bundling with projectRoot and externals and dependencies', () => {
});

test('esbuild bundling with pre compilations', () => {
Bundling.bundle({
entry,
projectRoot,
depsLockFilePath,
runtime: Runtime.NODEJS_14_X,
forceDockerBundling: true,
tsconfig,
preCompilation: true,
architecture: Architecture.X86_64,
});

// Correctly bundles with esbuild
expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), {
assetHashType: AssetHashType.OUTPUT,
bundling: expect.objectContaining({
command: [
'bash', '-c',
[
'tsc --project /asset-input/lib/custom-tsconfig.ts --rootDir ./ --outDir ./ &&',
'esbuild --bundle \"/asset-input/lib/handler.js\" --target=node14 --platform=node --outfile=\"/asset-output/index.js\"',
'--external:aws-sdk --tsconfig=/asset-input/lib/custom-tsconfig.ts',
].join(' '),
],
}),
});

Bundling.bundle({
entry,
projectRoot,
depsLockFilePath,
runtime: Runtime.NODEJS_14_X,
forceDockerBundling: true,
tsconfig,
preCompilation: true,
architecture: Architecture.X86_64,
});

// Correctly bundles with esbuild
expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), {
assetHashType: AssetHashType.OUTPUT,
bundling: expect.objectContaining({
command: [
'bash', '-c',
[
'esbuild --bundle \"/asset-input/lib/handler.js\" --target=node14 --platform=node --outfile=\"/asset-output/index.js\"',
'--external:aws-sdk --tsconfig=/asset-input/lib/custom-tsconfig.ts',
].join(' '),
],
}),
});

});

test('esbuild bundling with pre compilations with undefined tsconfig ( Should find in root directory )', () => {
Bundling.clearTscCompilationCache();
const packageLock = path.join(__dirname, '..', 'package-lock.json');

Bundling.bundle({
entry: __filename.replace('.js', '.ts'),
projectRoot: path.dirname(packageLock),
depsLockFilePath: packageLock,
runtime: Runtime.NODEJS_14_X,
forceDockerBundling: true,
preCompilation: true,
forceDockerBundling: true,
architecture: Architecture.X86_64,
});

const compilerOptions = util.getTsconfigCompilerOptions(path.join(__dirname, '..', 'tsconfig.json'));

// Correctly bundles with esbuild
expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(packageLock), {
assetHashType: AssetHashType.OUTPUT,
bundling: expect.objectContaining({
command: [
'bash', '-c',
[
'tsc --project /asset-input/tsconfig.json --rootDir ./ --outDir ./ &&',
'esbuild --bundle \"/asset-input/test/bundling.test.js\" --target=node14 --platform=node --outfile=\"/asset-output/index.js\"',
'--external:aws-sdk',
`tsc \"/asset-input/test/bundling.test.ts\" ${compilerOptions} &&`,
'esbuild --bundle \"/asset-input/test/bundling.test.js\" --target=node14 --platform=node --outfile=\"/asset-output/index.js\" --external:aws-sdk',
].join(' '),
],
}),
});
});

test('esbuild bundling with pre compilations and undefined tsconfig ( Should throw) ', () => {
test('throws with pre compilation and not found tsconfig', () => {
expect(() => {
Bundling.bundle({
entry,
Expand All @@ -668,7 +613,7 @@ test('esbuild bundling with pre compilations and undefined tsconfig ( Should thr
preCompilation: true,
architecture: Architecture.X86_64,
});
}).toThrow('Cannot find a tsconfig.json, please specify the prop: tsconfig');
}).toThrow('Cannot find a `tsconfig.json` but `preCompilation` is set to `true`, please specify it via `tsconfig`');

});

Expand Down
17 changes: 16 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/test/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as child_process from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import { callsites, exec, extractDependencies, findUp, findUpMultiple } from '../lib/util';
import { callsites, exec, extractDependencies, findUp, findUpMultiple, getTsconfigCompilerOptions } from '../lib/util';

beforeEach(() => {
jest.clearAllMocks();
Expand Down Expand Up @@ -179,3 +179,18 @@ describe('extractDependencies', () => {
fs.unlinkSync(pkgPath);
});
});

describe('getTsconfigCompilerOptions', () => {
test('should extract compiler options and returns as string', () => {
const tsconfig = path.join(__dirname, '..', 'tsconfig.json');
const compilerOptions = getTsconfigCompilerOptions(tsconfig);
expect(compilerOptions).toEqual([
'--alwaysStrict --charset utf8 --declaration --experimentalDecorators',
'--inlineSourceMap --inlineSources --lib es2019 --module CommonJS',
'--newLine lf --noEmitOnError --noFallthroughCasesInSwitch --noImplicitAny',
'--noImplicitReturns --noImplicitThis --noUnusedLocals --noUnusedParameters',
'--resolveJsonModule --strict --strictNullChecks --strictPropertyInitialization',
'--target ES2019 --rootDir ./ --outDir ./',
].join(' '));
});
});

0 comments on commit 6dd81c7

Please sign in to comment.