From 798beaa569d551ce0ac894e728600999cef63f28 Mon Sep 17 00:00:00 2001 From: Long Ho Date: Sat, 12 Sep 2020 12:51:37 -0400 Subject: [PATCH] feat: allow ast transformers to take in addl opts, fix #1942 --- docs/user/config/astTransformers.md | 36 ++++++---- e2e/__tests__/path-mapping.test.ts | 2 +- src/config/config-set.ts | 101 ++++++++++++++++++++++------ src/types.ts | 18 +++-- 4 files changed, 117 insertions(+), 40 deletions(-) diff --git a/docs/user/config/astTransformers.md b/docs/user/config/astTransformers.md index a2c58eadd2..e1c635dee5 100644 --- a/docs/user/config/astTransformers.md +++ b/docs/user/config/astTransformers.md @@ -7,8 +7,8 @@ TypeScript AST transformers and provide them to `ts-jest` to include into compil The option is `astTransformers` and it allows ones to specify which 3 types of TypeScript AST transformers to use with `ts-jest`: -- `before` means your transformers get run before TS ones, which means your transformers will get raw TS syntax -instead of transpiled syntax (e.g `import` instead of `require` or `define` ). +- `before` means your transformers get run before TS ones, which means your transformers will get raw TS syntax + instead of transpiled syntax (e.g `import` instead of `require` or `define` ). - `after` means your transformers get run after TS ones, which gets transpiled syntax. - `afterDeclarations` means your transformers get run during `d.ts` generation phase, allowing you to transform output type declarations. @@ -23,11 +23,17 @@ module.exports = { globals: { 'ts-jest': { astTransformers: { - before: ['my-custom-transformer'], + before: [ + 'my-custom-transformer', + { + path: 'my-custom-transformer-that-needs-extra-opts', + options: {}, + }, + ], }, - } - } -}; + }, + }, +} ```
@@ -40,7 +46,10 @@ module.exports = { "globals": { "ts-jest": { astTransformers: { - "before": ["my-custom-transformer"] + "before": ["my-custom-transformer", { + path: 'my-custom-transformer-that-needs-extra-opts', + options: {} + }] } } } @@ -55,9 +64,9 @@ module.exports = { `ts-jest` is able to expose transformers for public usage to provide the possibility to opt-in/out for users. Currently the exposed transformers are: -- `path-mapping` convert alias import/export to relative import/export path base on `paths` in `tsconfig`. -This transformer works similar to `moduleNameMapper` in `jest.config.js`. When using this transformer, one might not need -`moduleNameMapper` anymore. +- `path-mapping` convert alias import/export to relative import/export path base on `paths` in `tsconfig`. + This transformer works similar to `moduleNameMapper` in `jest.config.js`. When using this transformer, one might not need + `moduleNameMapper` anymore. #### Example of opt-in transformers @@ -72,9 +81,9 @@ module.exports = { astTransformers: { before: ['ts-jest/dist/transformers/path-mapping'], }, - } - } -}; + }, + }, +} ```
@@ -97,7 +106,6 @@ module.exports = {
- ### Writing custom TypeScript AST transformers To write a custom TypeScript AST transformers, one can take a look at [the one](https://github.com/kulshekhar/ts-jest/tree/master/src/transformers) that `ts-jest` is using. diff --git a/e2e/__tests__/path-mapping.test.ts b/e2e/__tests__/path-mapping.test.ts index 165ce2c8db..90d9c30aed 100644 --- a/e2e/__tests__/path-mapping.test.ts +++ b/e2e/__tests__/path-mapping.test.ts @@ -13,7 +13,7 @@ function executeTest(rootDirs?: string[]) { }, astTransformers: { before: [ - 'ts-jest/dist/transformers/path-mapping' + {path: 'ts-jest/dist/transformers/path-mapping'} ], }, }, diff --git a/src/config/config-set.ts b/src/config/config-set.ts index 2d941370aa..fc19f39a7a 100644 --- a/src/config/config-set.ts +++ b/src/config/config-set.ts @@ -56,10 +56,15 @@ import { TSError } from '../utils/ts-error' const logger = rootLogger.child({ namespace: 'config' }) +interface AstTransformerObj> { + module: AstTransformerDesc + options?: T +} + interface AstTransformer { - before: AstTransformerDesc[] - after?: AstTransformerDesc[] - afterDeclarations?: AstTransformerDesc[] + before: AstTransformerObj[] + after?: AstTransformerObj[] + afterDeclarations?: AstTransformerObj[] } /** * @internal @@ -184,29 +189,52 @@ export class ConfigSet { this.logger.warn(Deprecations.AstTransformerArrayConfig) transformers = { - before: astTransformers.map((transformerPath) => this.resolvePath(transformerPath, { nodeResolve: true })), + before: astTransformers.map((transformerPath) => ({ + path: this.resolvePath(transformerPath, { nodeResolve: true }), + })), } } else { if (astTransformers.before) { transformers = { - before: astTransformers.before.map((transformerPath: string) => - this.resolvePath(transformerPath, { nodeResolve: true }), + before: astTransformers.before.map((transformer) => + typeof transformer === 'string' + ? { + path: this.resolvePath(transformer, { nodeResolve: true }), + } + : { + ...transformer, + path: this.resolvePath(transformer.path, { nodeResolve: true }), + }, ), } } if (astTransformers.after) { transformers = { ...transformers, - after: astTransformers.after.map((transformerPath: string) => - this.resolvePath(transformerPath, { nodeResolve: true }), + after: astTransformers.after.map((transformer) => + typeof transformer === 'string' + ? { + path: this.resolvePath(transformer, { nodeResolve: true }), + } + : { + ...transformer, + path: this.resolvePath(transformer.path, { nodeResolve: true }), + }, ), } } if (astTransformers.afterDeclarations) { transformers = { ...transformers, - afterDeclarations: astTransformers.afterDeclarations.map((transformerPath: string) => - this.resolvePath(transformerPath, { nodeResolve: true }), + afterDeclarations: astTransformers.afterDeclarations.map((transformer) => + typeof transformer === 'string' + ? { + path: this.resolvePath(transformer, { nodeResolve: true }), + } + : { + ...transformer, + path: this.resolvePath(transformer.path, { nodeResolve: true }), + }, ), } } @@ -402,28 +430,57 @@ export class ConfigSet { @Memoize() private get astTransformers(): AstTransformer { let astTransformers: AstTransformer = { - before: [...internalAstTransformers], + before: [ + ...internalAstTransformers.map((transformer) => ({ + module: transformer, + })), + ], } const { transformers } = this.tsJest if (transformers.before) { astTransformers = { before: [ ...astTransformers.before, - ...transformers.before.map((transformerFilePath: string) => require(transformerFilePath)), + ...transformers.before.map((transformer) => + typeof transformer === 'string' + ? { + module: require(transformer), + } + : { + module: require(transformer.path), + options: transformer.options, + }, + ), ], } } if (transformers.after) { astTransformers = { ...astTransformers, - after: transformers.after.map((transformerFilePath: string) => require(transformerFilePath)), + after: transformers.after.map((transformer) => + typeof transformer === 'string' + ? { + module: require(transformer), + } + : { + module: require(transformer.path), + options: transformer.options, + }, + ), } } if (transformers.afterDeclarations) { astTransformers = { ...astTransformers, - afterDeclarations: transformers.afterDeclarations.map((transformerFilePath: string) => - require(transformerFilePath), + afterDeclarations: transformers.afterDeclarations.map((transformer) => + typeof transformer === 'string' + ? { + module: require(transformer), + } + : { + module: require(transformer.path), + options: transformer.options, + }, ), } } @@ -437,20 +494,24 @@ export class ConfigSet { @Memoize() get tsCustomTransformers(): CustomTransformers { let customTransformers: CustomTransformers = { - before: this.astTransformers.before.map((t) => t.factory(this)) as TransformerFactory[], + before: this.astTransformers.before.map((t) => t.module.factory(this, t.options)) as TransformerFactory< + SourceFile + >[], } if (this.astTransformers.after) { customTransformers = { ...customTransformers, - after: this.astTransformers.after.map((t) => t.factory(this)) as TransformerFactory[], + after: this.astTransformers.after.map((t) => t.module.factory(this, t.options)) as TransformerFactory< + SourceFile + >[], } } if (this.astTransformers.afterDeclarations) { customTransformers = { ...customTransformers, - afterDeclarations: this.astTransformers.afterDeclarations.map((t) => t.factory(this)) as TransformerFactory< - Bundle | SourceFile - >[], + afterDeclarations: this.astTransformers.afterDeclarations.map((t) => + t.module.factory(this, t.options), + ) as TransformerFactory[], } } diff --git a/src/types.ts b/src/types.ts index ef17b21cc6..882d3980f4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -24,10 +24,15 @@ export type BabelJestTransformer = { */ export type BabelConfig = _babel.TransformOptions +export interface AstTransformer> { + path: string + options?: T +} + export interface ConfigCustomTransformer { - before?: string[] - after?: string[] - afterDeclarations?: string[] + before?: (string | AstTransformer)[] + after?: (string | AstTransformer)[] + afterDeclarations?: (string | AstTransformer)[] } export interface TsJestGlobalOptions { @@ -229,8 +234,11 @@ export interface CompilerInstance { /** * @internal */ -export interface AstTransformerDesc { +export interface AstTransformerDesc> { name: string version: number - factory(cs: ConfigSet): _ts.TransformerFactory<_ts.SourceFile> | _ts.TransformerFactory<_ts.Bundle | _ts.SourceFile> + factory( + cs: ConfigSet, + opts?: T, + ): _ts.TransformerFactory<_ts.SourceFile> | _ts.TransformerFactory<_ts.Bundle | _ts.SourceFile> }