From fc9512024457f321244085f6de6548f92821d442 Mon Sep 17 00:00:00 2001 From: Larry Boltovskoi Date: Sun, 12 Jan 2020 16:05:16 +0000 Subject: [PATCH] Custom tsconfig.json, credits to @Knaackee --- README.md | 13 ++++++++++ src/Serverless.d.ts | 5 ++++ src/index.ts | 5 ++-- src/typescript.ts | 12 +++++++-- src/watchFiles.ts | 13 +++++++--- tests/custom.tsconfig.json | 5 ++++ tests/typescript.getTypescriptConfig.test.ts | 26 ++++++++++++++++++++ 7 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 tests/custom.tsconfig.json diff --git a/README.md b/README.md index dbcea723..7dca9518 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,19 @@ The default `tsconfig.json` file used by the plugin looks like this: > Note 2: Don't confuse the [`tsconfig.json`](tsconfig.json) in this repository with the one mentioned above. +### Custom Typescript Configuration + +This plugin will use your local `tsconfig.json` if it exists. You can configure a path to a custom Typescript configuration inside your `serverless.yml` using: + + ... + plugins: + - serverless-plugin-typescript + custom: + typeScript: + tsconfigFilePath: ./tsconfig.build.json + ... + + ### Including extra files All files from `package/include` will be included in the final build file. See [Exclude/Include](https://serverless.com/framework/docs/providers/aws/guide/packaging#exclude--include) diff --git a/src/Serverless.d.ts b/src/Serverless.d.ts index ec7d7049..d8a3f935 100644 --- a/src/Serverless.d.ts +++ b/src/Serverless.d.ts @@ -12,6 +12,11 @@ declare namespace Serverless { provider: { name: string } + custom: { + typeScript: { + tsconfigFilePath: string | undefined + } + }, functions: { [key: string]: Serverless.Function } diff --git a/src/index.ts b/src/index.ts index a249ce58..e260a165 100644 --- a/src/index.ts +++ b/src/index.ts @@ -118,7 +118,7 @@ export class TypeScriptPlugin { this.serverless.cli.log(`Watch function ${this.options.function}...`) this.isWatching = true - watchFiles(this.rootFileNames, this.originalServicePath, () => { + watchFiles(this.rootFileNames, this.originalServicePath, this.serverless, () => { this.serverless.pluginManager.spawn('invoke:local') }) } @@ -131,7 +131,7 @@ export class TypeScriptPlugin { this.serverless.cli.log(`Watching typescript files...`) this.isWatching = true - watchFiles(this.rootFileNames, this.originalServicePath, this.compileTs.bind(this)) + watchFiles(this.rootFileNames, this.originalServicePath, this.serverless, this.compileTs.bind(this)) } async compileTs(): Promise { @@ -147,6 +147,7 @@ export class TypeScriptPlugin { const tsconfig = typescript.getTypescriptConfig( this.originalServicePath, + this.serverless, this.isWatching ? null : this.serverless.cli ) diff --git a/src/typescript.ts b/src/typescript.ts index 22f7354a..004877f1 100644 --- a/src/typescript.ts +++ b/src/typescript.ts @@ -112,9 +112,17 @@ export function getSourceFiles( export function getTypescriptConfig( cwd: string, + serverless?: Serverless.Instance, logger?: { log: (str: string) => void } ): ts.CompilerOptions { - const configFilePath = path.join(cwd, 'tsconfig.json') + let configFilePath = path.join(cwd, 'tsconfig.json') + + if (serverless && serverless.service.custom && serverless.service.custom.typeScript && serverless.service.custom.typeScript.tsconfigFilePath) { + configFilePath = path.join(cwd, serverless.service.custom.typeScript.tsconfigFilePath) + if (!fs.existsSync(configFilePath)) { + throw new Error(`Custom Typescript Config File not found at "${configFilePath}"`) + } + } if (fs.existsSync(configFilePath)) { @@ -130,7 +138,7 @@ export function getTypescriptConfig( } if (logger) { - logger.log(`Using local tsconfig.json`) + logger.log(`Using local tsconfig.json "${configFilePath}"`) } // disallow overrriding rootDir diff --git a/src/watchFiles.ts b/src/watchFiles.ts index a231534a..19dd7ca6 100644 --- a/src/watchFiles.ts +++ b/src/watchFiles.ts @@ -1,8 +1,13 @@ import * as typescript from './typescript' -import { watchFile, unwatchFile, Stats} from 'fs' +import { watchFile, unwatchFile, Stats } from 'fs' -export function watchFiles(rootFileNames: string[], originalServicePath: string, cb: () => void) { - const tsConfig = typescript.getTypescriptConfig(originalServicePath) +export function watchFiles( + rootFileNames: string[], + originalServicePath: string, + serverless: Serverless.Instance, + cb: () => void +) { + const tsConfig = typescript.getTypescriptConfig(originalServicePath, serverless) let watchedFiles = typescript.getSourceFiles(rootFileNames, tsConfig) watchedFiles.forEach(fileName => { @@ -18,7 +23,7 @@ export function watchFiles(rootFileNames: string[], originalServicePath: string, cb() // use can reference not watched yet file or remove reference to already watched - const newWatchFiles = typescript.getSourceFiles(rootFileNames, tsConfig) + const newWatchFiles = typescript.getSourceFiles(rootFileNames, tsConfig) watchedFiles.forEach(fileName => { if (newWatchFiles.indexOf(fileName) < 0) { unwatchFile(fileName, watchCallback) diff --git a/tests/custom.tsconfig.json b/tests/custom.tsconfig.json new file mode 100644 index 00000000..ea71f941 --- /dev/null +++ b/tests/custom.tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "target": "es6" + } +} \ No newline at end of file diff --git a/tests/typescript.getTypescriptConfig.test.ts b/tests/typescript.getTypescriptConfig.test.ts index da80c772..939259ea 100644 --- a/tests/typescript.getTypescriptConfig.test.ts +++ b/tests/typescript.getTypescriptConfig.test.ts @@ -8,4 +8,30 @@ describe('getTypescriptConfig', () => { makeDefaultTypescriptConfig() ) }) + + it (`should throw an error if configured typescript configuration does not exist`, () => { + expect(() => + getTypescriptConfig(process.cwd(), { + service: { + custom: { + typeScript: { + tsconfigFilePath: "./some-path" + } + }} + } as any), + ).toThrowError("Custom Typescript Config File not found") + }) + + it (`returns configured typescript configuration if provided`, () => { + expect( + getTypescriptConfig(process.cwd(), { + service: { + custom: { + typeScript: { + tsconfigFilePath: "./tests/custom.tsconfig.json" + } + }} + } as any).target, + ).toEqual(2) + }) }) \ No newline at end of file