Skip to content

Commit 9b55404

Browse files
authoredJun 6, 2021
feat: emit ESM codes if using ESM mode with Babel (#2661)
Close #2650
1 parent 132c8ba commit 9b55404

File tree

3 files changed

+133
-36
lines changed

3 files changed

+133
-36
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": false, "useESM": true} 1`] = `
4+
Object {
5+
"allowSyntheticDefaultImports": undefined,
6+
"esModuleInterop": true,
7+
"module": 1,
8+
}
9+
`;
10+
11+
exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": true, "useESM": false} 1`] = `
12+
Object {
13+
"allowSyntheticDefaultImports": undefined,
14+
"esModuleInterop": true,
15+
"module": 1,
16+
}
17+
`;
18+
19+
exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": true, "useESM": true} 1`] = `
20+
Object {
21+
"allowSyntheticDefaultImports": true,
22+
"esModuleInterop": true,
23+
"module": 99,
24+
}
25+
`;
26+
27+
exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": true, "supportsStaticESM": false, "useESM": true} 1`] = `
28+
Object {
29+
"allowSyntheticDefaultImports": true,
30+
"esModuleInterop": true,
31+
"module": 99,
32+
}
33+
`;
34+
35+
exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": false, "supportsStaticESM": false, "useESM": true} 1`] = `
36+
Object {
37+
"allowSyntheticDefaultImports": undefined,
38+
"esModuleInterop": true,
39+
"module": 1,
40+
}
41+
`;
42+
43+
exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": false, "supportsStaticESM": true, "useESM": false} 1`] = `
44+
Object {
45+
"allowSyntheticDefaultImports": undefined,
46+
"esModuleInterop": true,
47+
"module": 1,
48+
}
49+
`;
50+
51+
exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": false, "supportsStaticESM": true, "useESM": true} 1`] = `
52+
Object {
53+
"allowSyntheticDefaultImports": true,
54+
"esModuleInterop": true,
55+
"module": 99,
56+
}
57+
`;
58+
59+
exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": true, "supportsStaticESM": false, "useESM": true} 1`] = `
60+
Object {
61+
"allowSyntheticDefaultImports": true,
62+
"esModuleInterop": true,
63+
"module": 99,
64+
}
65+
`;

‎src/compiler/ts-compiler.spec.ts

+64-35
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { readFileSync } from 'fs'
22
import { basename, join, normalize } from 'path'
33

4-
import { DiagnosticCategory, EmitOutput, ModuleKind, ScriptTarget, TranspileOutput } from 'typescript'
4+
import { CompilerOptions, DiagnosticCategory, EmitOutput, TranspileOutput } from 'typescript'
55

66
import { createConfigSet, makeCompiler } from '../__helpers__/fakers'
77
import { mockFolder } from '../__helpers__/path'
@@ -76,44 +76,57 @@ describe('TsCompiler', () => {
7676
const fileName = join(mockFolder, 'thing.ts')
7777
const fileContent = 'const bar = 1'
7878

79-
test.each([true, false])('should transpile code with useESM %p', (useESM) => {
79+
test.each([
80+
{
81+
useESM: true,
82+
babelConfig: true,
83+
supportsStaticESM: false,
84+
},
85+
{
86+
useESM: true,
87+
babelConfig: false,
88+
supportsStaticESM: true,
89+
},
90+
{
91+
useESM: true,
92+
babelConfig: false,
93+
supportsStaticESM: false,
94+
},
95+
{
96+
useESM: false,
97+
babelConfig: false,
98+
supportsStaticESM: true,
99+
},
100+
])('should transpile code with config %p', ({ useESM, babelConfig, supportsStaticESM }) => {
80101
const compiler = makeCompiler({
81-
tsJestConfig: { ...baseTsJestConfig, isolatedModules: true, useESM },
102+
tsJestConfig: { ...baseTsJestConfig, isolatedModules: true, useESM, babelConfig },
82103
})
83104
const transformersStub = {
84105
before: [],
85106
after: [],
86107
afterDeclarations: [],
87108
}
88109
// @ts-expect-error testing purpose
89-
compiler._ts.transpileModule = jest.fn().mockReturnValueOnce({
110+
const transpileMock = (compiler._ts.transpileModule = jest.fn().mockReturnValueOnce({
90111
sourceMapText: '{}',
91112
outputText: 'var bar = 1',
92113
diagnostics: [],
93-
} as TranspileOutput)
114+
} as TranspileOutput))
94115
// @ts-expect-error testing purpose
95116
compiler._makeTransformers = jest.fn().mockReturnValueOnce(transformersStub)
96117
compiler.getCompiledOutput(fileContent, fileName, {
97118
depGraphs: new Map(),
98-
supportsStaticESM: true,
119+
supportsStaticESM,
99120
watchMode: false,
100121
})
101-
// @ts-expect-error testing purpose
102-
const compilerOptions = compiler._compilerOptions
103122

104-
// @ts-expect-error testing purpose
105-
expect(compiler._ts.transpileModule).toHaveBeenCalledWith(fileContent, {
106-
fileName,
107-
compilerOptions: {
108-
...compilerOptions,
109-
module: useESM ? ModuleKind.ESNext : ModuleKind.CommonJS,
110-
target: useESM ? ScriptTarget.ES2015 : compilerOptions.target,
111-
esModuleInterop: useESM ? true : compilerOptions.esModuleInterop,
112-
allowSyntheticDefaultImports: useESM ? true : compilerOptions.allowSyntheticDefaultImports,
113-
},
114-
transformers: transformersStub,
115-
reportDiagnostics: compiler.configSet.shouldReportDiagnostics(fileName),
116-
})
123+
const usedCompilerOptions = transpileMock.mock.calls[0][1].compilerOptions as CompilerOptions
124+
expect(transpileMock).toHaveBeenCalled()
125+
expect({
126+
module: usedCompilerOptions.module,
127+
esModuleInterop: usedCompilerOptions.esModuleInterop,
128+
allowSyntheticDefaultImports: usedCompilerOptions.allowSyntheticDefaultImports,
129+
}).toMatchSnapshot()
117130
})
118131

119132
test.each([true, false])('should report diagnostics if shouldReportDiagnostics is %p', (shouldReport) => {
@@ -163,9 +176,30 @@ describe('TsCompiler', () => {
163176
const jsOutput = 'var bar = 1'
164177
const sourceMap = '{}'
165178

166-
test.each([true, false])('should compile codes with useESM %p', (useESM) => {
179+
test.each([
180+
{
181+
useESM: true,
182+
babelConfig: true,
183+
supportsStaticESM: false,
184+
},
185+
{
186+
useESM: true,
187+
babelConfig: false,
188+
supportsStaticESM: true,
189+
},
190+
{
191+
useESM: true,
192+
babelConfig: false,
193+
supportsStaticESM: false,
194+
},
195+
{
196+
useESM: false,
197+
babelConfig: false,
198+
supportsStaticESM: true,
199+
},
200+
])('should compile codes with useESM %p', ({ useESM, babelConfig, supportsStaticESM }) => {
167201
const configSet = createConfigSet({
168-
tsJestConfig: { ...baseTsJestConfig, useESM },
202+
tsJestConfig: { ...baseTsJestConfig, useESM, babelConfig },
169203
})
170204
const emptyFile = join(mockFolder, 'empty.ts')
171205
configSet.parsedTsConfig.fileNames.push(emptyFile)
@@ -180,22 +214,17 @@ describe('TsCompiler', () => {
180214

181215
const output = compiler.getCompiledOutput(fileContent, fileName, {
182216
depGraphs: new Map(),
183-
supportsStaticESM: true,
217+
supportsStaticESM,
184218
watchMode: false,
185219
})
186220

187221
// @ts-expect-error testing purpose
188-
const compileTarget = compiler._compilerOptions.target
189-
// @ts-expect-error testing purpose
190-
const moduleKind = compiler._compilerOptions.module
191-
// @ts-expect-error testing purpose
192-
const esModuleInterop = compiler._compilerOptions.esModuleInterop
193-
// @ts-expect-error testing purpose
194-
const allowSyntheticDefaultImports = compiler._compilerOptions.allowSyntheticDefaultImports
195-
expect(compileTarget).toEqual(useESM ? ScriptTarget.ES2015 : compileTarget)
196-
expect(moduleKind).toEqual(useESM ? ModuleKind.ESNext : moduleKind)
197-
expect(esModuleInterop).toEqual(useESM ? true : esModuleInterop)
198-
expect(allowSyntheticDefaultImports).toEqual(useESM ? true : allowSyntheticDefaultImports)
222+
const usedCompilerOptions = compiler._compilerOptions
223+
expect({
224+
module: usedCompilerOptions.module,
225+
esModuleInterop: usedCompilerOptions.esModuleInterop,
226+
allowSyntheticDefaultImports: usedCompilerOptions.allowSyntheticDefaultImports,
227+
}).toMatchSnapshot()
199228
expect(output).toEqual(updateOutput(jsOutput, fileName, sourceMap))
200229

201230
// @ts-expect-error testing purpose

‎src/compiler/ts-compiler.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ export class TsCompiler implements TsCompilerInstance {
150150
let esModuleInterop = this._initialCompilerOptions.esModuleInterop
151151
let allowSyntheticDefaultImports = this._initialCompilerOptions.allowSyntheticDefaultImports
152152
const currentModuleKind = this._compilerOptions.module
153-
if (options.supportsStaticESM && this.configSet.useESM) {
153+
if (
154+
(this.configSet.babelJestTransformer || (!this.configSet.babelJestTransformer && options.supportsStaticESM)) &&
155+
this.configSet.useESM
156+
) {
154157
moduleKind =
155158
!moduleKind ||
156159
(moduleKind &&

0 commit comments

Comments
 (0)
Please sign in to comment.