Skip to content

Commit

Permalink
feat: emit ESM codes if using ESM mode with Babel (#2661)
Browse files Browse the repository at this point in the history
Close #2650
  • Loading branch information
ahnpnl authored Jun 6, 2021
1 parent 132c8ba commit 9b55404
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 36 deletions.
65 changes: 65 additions & 0 deletions src/compiler/__snapshots__/ts-compiler.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": false, "useESM": true} 1`] = `
Object {
"allowSyntheticDefaultImports": undefined,
"esModuleInterop": true,
"module": 1,
}
`;

exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": true, "useESM": false} 1`] = `
Object {
"allowSyntheticDefaultImports": undefined,
"esModuleInterop": true,
"module": 1,
}
`;

exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": true, "useESM": true} 1`] = `
Object {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"module": 99,
}
`;

exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": true, "supportsStaticESM": false, "useESM": true} 1`] = `
Object {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"module": 99,
}
`;

exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": false, "supportsStaticESM": false, "useESM": true} 1`] = `
Object {
"allowSyntheticDefaultImports": undefined,
"esModuleInterop": true,
"module": 1,
}
`;

exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": false, "supportsStaticESM": true, "useESM": false} 1`] = `
Object {
"allowSyntheticDefaultImports": undefined,
"esModuleInterop": true,
"module": 1,
}
`;

exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": false, "supportsStaticESM": true, "useESM": true} 1`] = `
Object {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"module": 99,
}
`;

exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": true, "supportsStaticESM": false, "useESM": true} 1`] = `
Object {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"module": 99,
}
`;
99 changes: 64 additions & 35 deletions src/compiler/ts-compiler.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { readFileSync } from 'fs'
import { basename, join, normalize } from 'path'

import { DiagnosticCategory, EmitOutput, ModuleKind, ScriptTarget, TranspileOutput } from 'typescript'
import { CompilerOptions, DiagnosticCategory, EmitOutput, TranspileOutput } from 'typescript'

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

test.each([true, false])('should transpile code with useESM %p', (useESM) => {
test.each([
{
useESM: true,
babelConfig: true,
supportsStaticESM: false,
},
{
useESM: true,
babelConfig: false,
supportsStaticESM: true,
},
{
useESM: true,
babelConfig: false,
supportsStaticESM: false,
},
{
useESM: false,
babelConfig: false,
supportsStaticESM: true,
},
])('should transpile code with config %p', ({ useESM, babelConfig, supportsStaticESM }) => {
const compiler = makeCompiler({
tsJestConfig: { ...baseTsJestConfig, isolatedModules: true, useESM },
tsJestConfig: { ...baseTsJestConfig, isolatedModules: true, useESM, babelConfig },
})
const transformersStub = {
before: [],
after: [],
afterDeclarations: [],
}
// @ts-expect-error testing purpose
compiler._ts.transpileModule = jest.fn().mockReturnValueOnce({
const transpileMock = (compiler._ts.transpileModule = jest.fn().mockReturnValueOnce({
sourceMapText: '{}',
outputText: 'var bar = 1',
diagnostics: [],
} as TranspileOutput)
} as TranspileOutput))
// @ts-expect-error testing purpose
compiler._makeTransformers = jest.fn().mockReturnValueOnce(transformersStub)
compiler.getCompiledOutput(fileContent, fileName, {
depGraphs: new Map(),
supportsStaticESM: true,
supportsStaticESM,
watchMode: false,
})
// @ts-expect-error testing purpose
const compilerOptions = compiler._compilerOptions

// @ts-expect-error testing purpose
expect(compiler._ts.transpileModule).toHaveBeenCalledWith(fileContent, {
fileName,
compilerOptions: {
...compilerOptions,
module: useESM ? ModuleKind.ESNext : ModuleKind.CommonJS,
target: useESM ? ScriptTarget.ES2015 : compilerOptions.target,
esModuleInterop: useESM ? true : compilerOptions.esModuleInterop,
allowSyntheticDefaultImports: useESM ? true : compilerOptions.allowSyntheticDefaultImports,
},
transformers: transformersStub,
reportDiagnostics: compiler.configSet.shouldReportDiagnostics(fileName),
})
const usedCompilerOptions = transpileMock.mock.calls[0][1].compilerOptions as CompilerOptions
expect(transpileMock).toHaveBeenCalled()
expect({
module: usedCompilerOptions.module,
esModuleInterop: usedCompilerOptions.esModuleInterop,
allowSyntheticDefaultImports: usedCompilerOptions.allowSyntheticDefaultImports,
}).toMatchSnapshot()
})

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

test.each([true, false])('should compile codes with useESM %p', (useESM) => {
test.each([
{
useESM: true,
babelConfig: true,
supportsStaticESM: false,
},
{
useESM: true,
babelConfig: false,
supportsStaticESM: true,
},
{
useESM: true,
babelConfig: false,
supportsStaticESM: false,
},
{
useESM: false,
babelConfig: false,
supportsStaticESM: true,
},
])('should compile codes with useESM %p', ({ useESM, babelConfig, supportsStaticESM }) => {
const configSet = createConfigSet({
tsJestConfig: { ...baseTsJestConfig, useESM },
tsJestConfig: { ...baseTsJestConfig, useESM, babelConfig },
})
const emptyFile = join(mockFolder, 'empty.ts')
configSet.parsedTsConfig.fileNames.push(emptyFile)
Expand All @@ -180,22 +214,17 @@ describe('TsCompiler', () => {

const output = compiler.getCompiledOutput(fileContent, fileName, {
depGraphs: new Map(),
supportsStaticESM: true,
supportsStaticESM,
watchMode: false,
})

// @ts-expect-error testing purpose
const compileTarget = compiler._compilerOptions.target
// @ts-expect-error testing purpose
const moduleKind = compiler._compilerOptions.module
// @ts-expect-error testing purpose
const esModuleInterop = compiler._compilerOptions.esModuleInterop
// @ts-expect-error testing purpose
const allowSyntheticDefaultImports = compiler._compilerOptions.allowSyntheticDefaultImports
expect(compileTarget).toEqual(useESM ? ScriptTarget.ES2015 : compileTarget)
expect(moduleKind).toEqual(useESM ? ModuleKind.ESNext : moduleKind)
expect(esModuleInterop).toEqual(useESM ? true : esModuleInterop)
expect(allowSyntheticDefaultImports).toEqual(useESM ? true : allowSyntheticDefaultImports)
const usedCompilerOptions = compiler._compilerOptions
expect({
module: usedCompilerOptions.module,
esModuleInterop: usedCompilerOptions.esModuleInterop,
allowSyntheticDefaultImports: usedCompilerOptions.allowSyntheticDefaultImports,
}).toMatchSnapshot()
expect(output).toEqual(updateOutput(jsOutput, fileName, sourceMap))

// @ts-expect-error testing purpose
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/ts-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ export class TsCompiler implements TsCompilerInstance {
let esModuleInterop = this._initialCompilerOptions.esModuleInterop
let allowSyntheticDefaultImports = this._initialCompilerOptions.allowSyntheticDefaultImports
const currentModuleKind = this._compilerOptions.module
if (options.supportsStaticESM && this.configSet.useESM) {
if (
(this.configSet.babelJestTransformer || (!this.configSet.babelJestTransformer && options.supportsStaticESM)) &&
this.configSet.useESM
) {
moduleKind =
!moduleKind ||
(moduleKind &&
Expand Down

0 comments on commit 9b55404

Please sign in to comment.