Skip to content

Commit

Permalink
feat(config): exposes custom transformers to config for presets
Browse files Browse the repository at this point in the history
  • Loading branch information
huafu committed Sep 5, 2018
1 parent f95b880 commit 885bc44
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/__helpers__/fakers.ts
Expand Up @@ -57,6 +57,7 @@ export function tsJestConfig(options?: Partial<TsJestConfig>): TsJestConfig {
return {
isolatedModules: false,
compiler: 'typescript',
transformers: [],
babelConfig: undefined,
tsConfig: undefined,
stringifyContentPathRegex: undefined,
Expand Down
5 changes: 1 addition & 4 deletions src/compiler.ts
Expand Up @@ -35,10 +35,8 @@ import stableStringify = require('fast-json-stable-stringify')
import { readFileSync, writeFileSync } from 'fs'
import mkdirp = require('mkdirp')
import { basename, extname, join, relative } from 'path'
import { CustomTransformers } from 'typescript'

import { ConfigSet } from './config/config-set'
import { factory as customTransformersFactory } from './transformers'
import { MemoryCache, TsCompiler, TypeInfo } from './types'
import { Errors, interpolate } from './util/messages'
import { sha1 } from './util/sha1'
Expand Down Expand Up @@ -88,8 +86,7 @@ export function createCompiler(configs: ConfigSet): TsCompiler {
? (path: string) => (/\.[tj]sx$/.test(path) ? '.jsx' : '.js')
: (_: string) => '.js'

// TODO: grab internal transformers
const transformers: CustomTransformers = customTransformersFactory(configs)
const transformers = configs.tsCustomTransformers

/**
* Create the basic required function using transpile mode.
Expand Down
1 change: 1 addition & 0 deletions src/config/__snapshots__/config-set.spec.ts.snap
Expand Up @@ -32,6 +32,7 @@ Object {
},
"isolatedModules": false,
"stringifyContentPathRegex": undefined,
"transformers": Array [],
"tsConfig": Object {
"kind": "file",
"value": undefined,
Expand Down
45 changes: 41 additions & 4 deletions src/config/config-set.ts
Expand Up @@ -13,11 +13,13 @@ import { existsSync, readFileSync } from 'fs'
import json5 from 'json5'
import { dirname, isAbsolute, join, resolve } from 'path'
import semver from 'semver'
import { Diagnostic, FormatDiagnosticsHost, ParsedCommandLine } from 'typescript'
import { CustomTransformers, Diagnostic, FormatDiagnosticsHost, ParsedCommandLine } from 'typescript'

import { version as myVersion } from '..'
import { createCompiler } from '../compiler'
import { internals as internalAstTransformers } from '../transformers'
import {
AstTransformerDesc,
BabelConfig,
BabelJestTransformer,
TTypeScript,
Expand Down Expand Up @@ -160,6 +162,9 @@ export class ConfigSet {
}
}

// transformers
const transformers = (options.astTransformers || []).map(mod => this.resolvePath(mod, { nodeResolve: true }))

// babel jest
const { babelConfig: babelConfigOpt } = options
let babelConfig: TsJestConfig['babelConfig']
Expand Down Expand Up @@ -210,6 +215,7 @@ export class ConfigSet {
diagnostics,
isolatedModules: !!options.isolatedModules,
compiler: options.compiler || 'typescript',
transformers,
stringifyContentPathRegex,
}
this.logger.debug({ tsJestConfig: res }, 'normalized ts-jest config')
Expand Down Expand Up @@ -316,6 +322,18 @@ export class ConfigSet {
return createCompiler(this)
}

@Memoize()
get astTransformers(): AstTransformerDesc[] {
return [...internalAstTransformers, ...this.tsJest.transformers.map(m => require(m))]
}

@Memoize()
get tsCustomTransformers(): CustomTransformers {
return {
before: this.astTransformers.map(t => t.factory(this)),
}
}

@Memoize()
get hooks(): TsJestHooksMap {
let hooksFile = process.env.TS_JEST_HOOKS
Expand Down Expand Up @@ -487,14 +505,32 @@ export class ConfigSet {
return { input, resolved: result }
}

resolvePath(inputPath: string, noFailIfMissing = false): string {
resolvePath(
inputPath: string,
{ throwIfMissing = true, nodeResolve = false }: { throwIfMissing?: boolean; nodeResolve?: boolean } = {},
): string {
let path: string = inputPath
let nodeResolved = false
if (path.startsWith('<rootDir>')) {
path = resolve(this.rootDir, path.substr(9))
} else if (!isAbsolute(path)) {
path = resolve(this.cwd, path)
if (!path.startsWith('.') && nodeResolve) {
try {
path = require.resolve(path)
nodeResolved = true
} catch (_) {}
}
if (!nodeResolved) {
path = resolve(this.cwd, path)
}
}
if (!nodeResolved && nodeResolve) {
try {
path = require.resolve(path)
nodeResolved = true
} catch (_) {}
}
if (!noFailIfMissing && !existsSync(path)) {
if (throwIfMissing && !existsSync(path)) {
throw new Error(interpolate(Errors.FileNotFound, { inputPath, resolvedPath: path }))
}
this.logger.debug({ fromPath: inputPath, toPath: path }, 'resolved path from', inputPath, 'to', path)
Expand All @@ -514,6 +550,7 @@ export class ConfigSet {

return new JsonableValue({
versions: this.versions,
transformers: this.astTransformers.map(t => `${t.name}@${t.version}`),
jest,
tsJest: this.tsJest,
babel: this.babel,
Expand Down
5 changes: 5 additions & 0 deletions src/transformers/README.md
Expand Up @@ -13,6 +13,11 @@ import {
} from 'typescript';
import { ConfigSet } from '../config-set'

// this is a unique identifier for your transformer
export const name = 'my-transformer'
// increment this each time you change the behavior of your transformer
export const version = 1

export function factory(cs: ConfigSet) {
const ts = cs.compilerModule
function createVisitor(ctx: TransformationContext, sf: SourceFile) {
Expand Down
4 changes: 4 additions & 0 deletions src/transformers/hoisting.ts
Expand Up @@ -19,6 +19,10 @@ import { ConfigSet } from '../config/config-set'
*/
const HOIST_METHODS = ['mock', 'unmock']

export const name = 'hoisting-jest-mock'
// increment this each time the code is modified
export const version = 1

/**
* The factory of hoisting transformer factory
* @param cs Current jest configuration-set
Expand Down
12 changes: 3 additions & 9 deletions src/transformers/index.ts
@@ -1,11 +1,5 @@
import { CustomTransformers } from 'typescript'
import { AstTransformerDesc } from '../types'

import { ConfigSet } from '../config/config-set'
import * as hoisting from './hoisting'

import { factory as hoistingFactory } from './hoisting'

export function factory(cs: ConfigSet): CustomTransformers {
return {
before: [hoistingFactory(cs)],
}
}
export const internals: AstTransformerDesc[] = [hoisting]
16 changes: 15 additions & 1 deletion src/types.ts
@@ -1,5 +1,7 @@
import * as _babel from 'babel__core'
import _ts, { CompilerOptions } from 'typescript'
import _ts, { CompilerOptions, SourceFile, TransformerFactory } from 'typescript'

import { ConfigSet } from './config/config-set'

export type TBabelCore = typeof _babel
export type TTypeScript = typeof _ts
Expand Down Expand Up @@ -29,6 +31,11 @@ export interface TsJestGlobalOptions {
*/
compiler?: string

/**
* Custom transformers (mostly used by jest presets)
*/
astTransformers?: string[]

/**
* TS diagnostics - less to be reported if `isolatedModules` is `true`. It can be:
* - `true` (or `undefined`, it's the default): show all diagnostics
Expand Down Expand Up @@ -92,6 +99,7 @@ export interface TsJestConfig {
compiler: string
diagnostics: TsJestConfig$diagnostics
babelConfig: TsJestConfig$babelConfig
transformers: string[]

// to deprecate / deprecated === === ===
stringifyContentPathRegex: TsJestConfig$stringifyContentPathRegex
Expand Down Expand Up @@ -158,3 +166,9 @@ export interface TsCompiler {
compile(code: string, fileName: string, lineOffset?: number): string
getTypeInfo(code: string, fileName: string, position: number): TypeInfo
}

export interface AstTransformerDesc {
name: string
version: number
factory(cs: ConfigSet): TransformerFactory<SourceFile>
}

0 comments on commit 885bc44

Please sign in to comment.