Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: User defined tsconfig paths #205

Merged
merged 2 commits into from
Sep 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ The default `tsconfig.json` file used by the plugin looks like this:

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)

### Non-standard tsconfig.json locations
Override what tsconfig.json to use with the following snippet in your severless.yaml
```
custom:
serverlessPluginTypescript:
tsConfigFileLocation: './tsconfig.build.json'

```

## Usage

Expand Down
5 changes: 5 additions & 0 deletions src/Serverless.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ declare namespace Serverless {
}
package: Serverless.Package
getAllFunctions(): string[]
custom?: {
serverlessPluginTypescript?: {
tsConfigFileLocation: string
}
}
}

pluginManager: PluginManager
Expand Down
9 changes: 8 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,16 @@ export class TypeScriptPlugin {
// Fake service path so that serverless will know what to zip
this.serverless.config.servicePath = path.join(this.originalServicePath, BUILD_FOLDER)
}

let tsConfigFileLocation: string | undefined
if (
this.serverless.service.custom !== undefined
&& this.serverless.service.custom.serverlessPluginTypescript !== undefined
) {
tsConfigFileLocation = this.serverless.service.custom.serverlessPluginTypescript.tsConfigFileLocation
}
const tsconfig = typescript.getTypescriptConfig(
this.originalServicePath,
tsConfigFileLocation,
this.isWatching ? null : this.serverless.cli
)

Expand Down
12 changes: 8 additions & 4 deletions src/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,20 @@ export function getSourceFiles(

export function getTypescriptConfig(
cwd: string,
tsConfigFileLocation: string = 'tsconfig.json',
logger?: { log: (str: string) => void }
): ts.CompilerOptions {
const configFilePath = path.join(cwd, 'tsconfig.json')
const configFilePath = path.join(cwd, tsConfigFileLocation)

if (fs.existsSync(configFilePath)) {

const configFileText = fs.readFileSync(configFilePath).toString()
const result = ts.parseConfigFileTextToJson(configFilePath, configFileText)
if (result.error) {
throw new Error(JSON.stringify(result.error))
try {
throw new Error(JSON.stringify(result.error))
} catch (err) {
throw new Error('Invalid TSConfig file - is this file JSON format?')
}
}

const configParseResult = ts.parseJsonConfigFileContent(result.config, ts.sys, path.dirname(configFilePath))
Expand All @@ -130,7 +134,7 @@ export function getTypescriptConfig(
}

if (logger) {
logger.log(`Using local tsconfig.json`)
logger.log(`Using local tsconfig.json - ${tsConfigFileLocation}`)
}

// disallow overrriding rootDir
Expand Down
1 change: 1 addition & 0 deletions tests/assets/tsconfigs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const test = 'example'
13 changes: 13 additions & 0 deletions tests/assets/tsconfigs/tsconfig.default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"preserveConstEnums": true,
"strictNullChecks": true,
"sourceMap": true,
"allowJs": true,
"target": "es5",
"outDir": ".build",
"moduleResolution": "node",
"lib": ["es2015"],
"rootDir": "./"
}
}
1 change: 1 addition & 0 deletions tests/assets/tsconfigs/tsconfig.invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is not a tsconfig.json file
38 changes: 37 additions & 1 deletion tests/typescript.getTypescriptConfig.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {getTypescriptConfig, makeDefaultTypescriptConfig} from '../src/typescript'
import * as path from 'path'

describe('getTypescriptConfig', () => {
it(`returns default typescript configuration if the one provided doesn't exist`, () => {
Expand All @@ -8,4 +9,39 @@ describe('getTypescriptConfig', () => {
makeDefaultTypescriptConfig()
)
})
})

it(`returns default typescript configuration if the one provided doesn't exist when tsConfigFileLocation provided`, () => {
expect(
getTypescriptConfig(process.cwd(), './tests/assets/tsconfigs/tsconfig.nonexistent.json'),
).toEqual(
makeDefaultTypescriptConfig()
)
})

it(`returns custom typescript configuration if tsConfigFileLocation provided`, () => {
const tsconfigDir = path.join(process.cwd(), './tests/assets/tsconfigs/')
expect(
getTypescriptConfig(tsconfigDir, 'tsconfig.default.json'),
).toEqual({
allowJs: true,
configFilePath: undefined,
lib: ["lib.es2015.d.ts"],
moduleResolution: 2,
outDir: path.join(tsconfigDir, '.build'),
preserveConstEnums: true,
rootDir: tsconfigDir,
sourceMap: true,
strictNullChecks: true,
target: 1
})
})

it(`throws error if configuration from tsConfigFileLocation is invalid`, () => {
expect.assertions(1)
try {
getTypescriptConfig(process.cwd(), './tests/assets/tsconfigs/tsconfig.invalid.json')
} catch (e) {
expect(e.message).toBe('Invalid TSConfig file - is this file JSON format?')
}
})
})