Skip to content

Commit

Permalink
Update bundled transpileModule implementation to match latest TS co…
Browse files Browse the repository at this point in the history
…debase (#1973)

* empty initial commit

* Update bundled `transpileModule` implementation to match latest TS 5.0 codebase

* Add test; move transpile-only tests to their own file
  • Loading branch information
cspotcode committed Mar 18, 2023
1 parent fd43821 commit 6558cbe
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 28 deletions.
2 changes: 2 additions & 0 deletions src/test/helpers/version-checks.ts
Expand Up @@ -40,6 +40,8 @@ export const tsSupportsAllowImportingTsExtensions = semver.gte(
);
// TS 5.0 adds ability for tsconfig to `"extends": []` an array of configs
export const tsSupportsExtendsArray = semver.gte(ts.version, '4.999.999');
// TS 5.0 adds verbatimModuleSyntax
export const tsSupportsVerbatimModuleSyntax = semver.gte(ts.version, '5.0.0');
// Relevant when @tsconfig/bases refers to es2021 and we run tests against
// old TS versions.
export const tsSupportsEs2021 = semver.gte(ts.version, '4.3.0');
Expand Down
22 changes: 0 additions & 22 deletions src/test/index.spec.ts
Expand Up @@ -305,28 +305,6 @@ test.suite('ts-node', (test) => {
);
});

test('should support transpile only mode', async () => {
const r = await exec(
`${CMD_TS_NODE_WITH_PROJECT_FLAG} --transpile-only -pe "x"`
);
if (r.err === null) {
throw new Error('Command was expected to fail, but it succeeded.');
}

expect(r.err.message).toMatch('ReferenceError: x is not defined');
});

test('should throw error even in transpileOnly mode', async () => {
const r = await exec(
`${CMD_TS_NODE_WITH_PROJECT_FLAG} --transpile-only -pe "console."`
);
if (r.err === null) {
throw new Error('Command was expected to fail, but it succeeded.');
}

expect(r.err.message).toMatch('error TS1003: Identifier expected');
});

for (const flavor of [
'--transpiler ts-node/transpilers/swc transpile-only-swc',
'--transpiler ts-node/transpilers/swc-experimental transpile-only-swc',
Expand Down
51 changes: 51 additions & 0 deletions src/test/transpile-only.spec.ts
@@ -0,0 +1,51 @@
import { createExec } from './exec-helpers';
import { ctxTsNode, tsSupportsVerbatimModuleSyntax } from './helpers';
import { CMD_TS_NODE_WITH_PROJECT_FLAG } from './helpers/command-lines';
import { TEST_DIR } from './helpers/paths';
import { expect, context } from './testlib';

const test = context(ctxTsNode);

const exec = createExec({
cwd: TEST_DIR,
});

test('should support transpile only mode', async () => {
const r = await exec(
`${CMD_TS_NODE_WITH_PROJECT_FLAG} --transpile-only -pe "x"`
);
if (r.err === null) {
throw new Error('Command was expected to fail, but it succeeded.');
}

expect(r.err.message).toMatch('ReferenceError: x is not defined');
});

test('should throw error even in transpileOnly mode', async () => {
const r = await exec(
`${CMD_TS_NODE_WITH_PROJECT_FLAG} --transpile-only -pe "console."`
);
if (r.err === null) {
throw new Error('Command was expected to fail, but it succeeded.');
}

expect(r.err.message).toMatch('error TS1003: Identifier expected');
});

test.suite(
'verbatimModuleSyntax w/transpileOnly should not raise configuration diagnostic',
(test) => {
test.if(tsSupportsVerbatimModuleSyntax);
test('test', async (t) => {
// Mixing verbatimModuleSyntax w/transpileOnly
// https://github.com/TypeStrong/ts-node/issues/1971
// We should *not* get:
// "error TS5104: Option 'isolatedModules' is redundant and cannot be specified with option 'verbatimModuleSyntax'."
const service = t.context.tsNodeUnderTest.create({
transpileOnly: true,
compilerOptions: { verbatimModuleSyntax: true },
});
service.compile('const foo: string = 123', 'module.ts');
});
}
);
34 changes: 28 additions & 6 deletions src/ts-transpile-module.ts
@@ -1,3 +1,6 @@
// Derived from
// https://github.com/microsoft/TypeScript/blob/ae1b3db8ceaae7e93bddffa1eed26309068249d7/src/services/transpile.ts

import type {
CompilerHost,
CompilerOptions,
Expand All @@ -8,6 +11,12 @@ import type {
} from 'typescript';
import type { TSCommon } from './ts-compiler-types';

const optionsRedundantWithVerbatimModuleSyntax = new Set([
'isolatedModules',
'preserveValueImports',
'importsNotUsedAsValues',
]);

/** @internal */
export function createTsTranspileModule(
ts: TSCommon,
Expand All @@ -29,7 +38,6 @@ export function createTsTranspileModule(
Debug,
toPath,
getSetExternalModuleIndicator,
getEntries,
addRange,
hasProperty,
getEmitScriptTarget,
Expand All @@ -54,6 +62,14 @@ export function createTsTranspileModule(
}

for (const option of transpileOptionValueCompilerOptions) {
// Do not set redundant config options if `verbatimModuleSyntax` was supplied.
if (
options.verbatimModuleSyntax &&
optionsRedundantWithVerbatimModuleSyntax.has(option.name)
) {
continue;
}

options[option.name] = option.transpileOptionValue;
}

Expand Down Expand Up @@ -109,12 +125,18 @@ export function createTsTranspileModule(

return transpileModule;

/*
* This function will compile source text from 'input' argument using specified compiler options.
* If not options are provided - it will use a set of default compiler options.
* Extra compiler options that will unconditionally be used by this function are:
* - isolatedModules = true
* - allowNonTsExtensions = true
* - noLib = true
* - noResolve = true
*/
function transpileModule(
input: string,
transpileOptions2: Pick<
TranspileOptions,
'fileName' | 'moduleName' | 'renamedDependencies'
>,
transpileOptions2: TranspileOptions,
packageJsonType: 'module' | 'commonjs' = 'commonjs'
): TranspileOutput {
// if jsx is specified then treat file as .tsx
Expand Down Expand Up @@ -142,7 +164,7 @@ export function createTsTranspileModule(

if (transpileOptions2.renamedDependencies) {
(sourceFile as any).renamedDependencies = new Map(
getEntries(transpileOptions2.renamedDependencies)
Object.entries(transpileOptions2.renamedDependencies)
);
}

Expand Down

0 comments on commit 6558cbe

Please sign in to comment.