forked from swc-project/jest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
97 lines (78 loc) · 2.64 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import * as fs from 'fs'
import * as path from 'path'
import * as vm from 'vm'
import getCacheKeyFunction from '@jest/create-cache-key-function';
import { transformSync, Options } from '@swc/core'
interface JestConfig {
transform: [match: string, transformerPath: string, options: Options][];
extensionsToTreatAsEsm?: string[]
}
interface JestTransformerOption {
config: JestConfig;
transformerConfig: Options;
}
/**
* Loads closes package.json in the directory hierarchy
*/
function loadClosesPackageJson(attempts = 1): Record<string, unknown> {
if (attempts > 5) {
throw new Error('Can\'t resolve main package.json file');
}
var mainPath = attempts === 1 ? './' : Array(attempts).join("../");
try {
return require(mainPath + 'package.json');
} catch (e) {
return loadClosesPackageJson(attempts + 1);
}
}
const packageConfig = loadClosesPackageJson()
const isEsmProject = packageConfig.type === 'module'
// Jest use the `vm` [Module API](https://nodejs.org/api/vm.html#vm_class_vm_module) for ESM.
// see https://github.com/facebook/jest/issues/9430
const isSupportEsm = 'Module' in vm
function createTransformer(swcTransformOpts?: Options) {
swcTransformOpts = buildSwcTransformOpts(swcTransformOpts)
return {
process(src: string, filename: string, jestOptions: any) {
if (isSupportEsm) {
set(swcTransformOpts, 'module.type', isEsm(filename, jestOptions) ? 'es6' : 'commonjs')
}
return transformSync(src, { ...swcTransformOpts, filename })
},
getCacheKey: getCacheKeyFunction([], [JSON.stringify(swcTransformOpts)])
}
}
export = { createTransformer };
function buildSwcTransformOpts(swcOptions: any) {
if (!swcOptions) {
const swcrc = path.join(process.cwd(), '.swcrc')
swcOptions = fs.existsSync(swcrc) ? JSON.parse(fs.readFileSync(swcrc, 'utf-8')) as Options : {}
}
if (!isSupportEsm) {
set(swcOptions, 'module.type', 'commonjs')
}
set(swcOptions, 'jsc.transform.hidden.jest', true)
set(swcOptions, 'swcrc', false)
return swcOptions
}
function getJestConfig(jestConfig: JestConfig | JestTransformerOption) {
return 'config' in jestConfig
// jest 27
? jestConfig.config
// jest 26
: jestConfig
}
function isEsm(filename: string, jestOptions: any) {
return (/\.jsx?$/.test(filename) && isEsmProject) ||
getJestConfig(jestOptions).extensionsToTreatAsEsm?.find((ext: string) => filename.endsWith(ext))
}
function set(obj: any, path: string, value: any) {
let o = obj
const parents = path.split('.')
const key = parents.pop() as string
for (const prop of parents) {
if (o[prop] == null) o[prop] = {}
o = o[prop]
}
o[key] = value
}