Skip to content

Commit e41dbcd

Browse files
committed
Support json module emit when module emit is commonjs, amd, es2015 or esnext
Fixes #25755 and #26020
1 parent cbdfc01 commit e41dbcd

16 files changed

+97
-51
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2252,7 +2252,7 @@ namespace ts {
22522252
else if (!compilerOptions.resolveJsonModule &&
22532253
fileExtensionIs(moduleReference, Extension.Json) &&
22542254
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs &&
2255-
getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) {
2255+
hasJsonModuleEmitEnabled(compilerOptions)) {
22562256
error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference);
22572257
}
22582258
else {

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2892,7 +2892,7 @@
28922892
"category": "Error",
28932893
"code": 5070
28942894
},
2895-
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": {
2895+
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.": {
28962896
"category": "Error",
28972897
"code": 5071
28982898
},

src/compiler/emitter.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1780,7 +1780,9 @@ namespace ts {
17801780

17811781
function emitExpressionStatement(node: ExpressionStatement) {
17821782
emitExpression(node.expression);
1783-
if (!isJsonSourceFile(currentSourceFile)) {
1783+
// Emit semicolon in non json files
1784+
// or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
1785+
if (!isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) {
17841786
writeSemicolon();
17851787
}
17861788
}

src/compiler/program.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2549,9 +2549,9 @@ namespace ts {
25492549
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
25502550
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
25512551
}
2552-
// Any emit other than common js is error
2553-
else if (getEmitModuleKind(options) !== ModuleKind.CommonJS) {
2554-
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs, "resolveJsonModule", "module");
2552+
// Any emit other than common js, amd, es2015 or esnext is error
2553+
else if (!hasJsonModuleEmitEnabled(options)) {
2554+
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module");
25552555
}
25562556
}
25572557

src/compiler/transformers/module/module.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ namespace ts {
5353
* @param node The SourceFile node.
5454
*/
5555
function transformSourceFile(node: SourceFile) {
56-
if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & TransformFlags.ContainsDynamicImport)) {
56+
if (node.isDeclarationFile ||
57+
!(isEffectiveExternalModule(node, compilerOptions) ||
58+
node.transformFlags & TransformFlags.ContainsDynamicImport ||
59+
(isJsonSourceFile(node) && hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) {
5760
return node;
5861
}
5962

@@ -117,6 +120,7 @@ namespace ts {
117120
function transformAMDModule(node: SourceFile) {
118121
const define = createIdentifier("define");
119122
const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions);
123+
const jsonSourceFile = isJsonSourceFile(node) && node;
120124

121125
// An AMD define function has the following shape:
122126
//
@@ -158,7 +162,7 @@ namespace ts {
158162
// Add the dependency array argument:
159163
//
160164
// ["require", "exports", module1", "module2", ...]
161-
createArrayLiteral([
165+
createArrayLiteral(jsonSourceFile ? emptyArray : [
162166
createLiteral("require"),
163167
createLiteral("exports"),
164168
...aliasedModuleNames,
@@ -168,7 +172,9 @@ namespace ts {
168172
// Add the module body function argument:
169173
//
170174
// function (require, exports, module1, module2) ...
171-
createFunctionExpression(
175+
jsonSourceFile ?
176+
jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : createObjectLiteral() :
177+
createFunctionExpression(
172178
/*modifiers*/ undefined,
173179
/*asteriskToken*/ undefined,
174180
/*name*/ undefined,

src/compiler/utilities.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7004,6 +7004,18 @@ namespace ts {
70047004
return moduleResolution;
70057005
}
70067006

7007+
export function hasJsonModuleEmitEnabled(options: CompilerOptions) {
7008+
switch (getEmitModuleKind(options)) {
7009+
case ModuleKind.CommonJS:
7010+
case ModuleKind.AMD:
7011+
case ModuleKind.ES2015:
7012+
case ModuleKind.ESNext:
7013+
return true;
7014+
default:
7015+
return false;
7016+
}
7017+
}
7018+
70077019
export function unreachableCodeIsError(options: CompilerOptions): boolean {
70087020
return options.allowUnreachableCode === false;
70097021
}

tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts] ////
2+
3+
//// [file1.ts]
4+
import * as b from './b.json';
5+
6+
//// [b.json]
7+
{
8+
"a": true,
9+
"b": "hello"
10+
}
11+
12+
//// [out/output.js]
13+
define("b", [], {
14+
"a": true,
15+
"b": "hello"
16+
});
17+
define("file1", ["require", "exports"], function (require, exports) {
18+
"use strict";
19+
exports.__esModule = true;
20+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
import * as b from './b.json';
3+
>b : Symbol(b, Decl(file1.ts, 0, 6))
4+
5+
=== tests/cases/compiler/b.json ===
6+
{
7+
"a": true,
8+
>"a" : Symbol("a", Decl(b.json, 0, 1))
9+
10+
"b": "hello"
11+
>"b" : Symbol("b", Decl(b.json, 1, 14))
12+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
import * as b from './b.json';
3+
>b : { "a": boolean; "b": string; }
4+
5+
=== tests/cases/compiler/b.json ===
6+
{
7+
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
8+
9+
"a": true,
10+
>"a" : boolean
11+
>true : true
12+
13+
"b": "hello"
14+
>"b" : string
15+
>"hello" : "hello"
16+
}

tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt

Lines changed: 0 additions & 12 deletions
This file was deleted.

tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt

Lines changed: 0 additions & 12 deletions
This file was deleted.

tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
1+
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.
22
tests/cases/compiler/file1.ts(1,1): error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
33

44

5-
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
5+
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.
66
==== tests/cases/compiler/file1.ts (1 errors) ====
77
import * as b from './b.json';
88
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
1+
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.
22

33

4-
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
4+
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.
55
==== tests/cases/compiler/file1.ts (0 errors) ====
66
import * as b from './b.json';
77

tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
1+
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.
22

33

4-
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
4+
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.
55
==== tests/cases/compiler/file1.ts (0 errors) ====
66
import * as b from './b.json';
77

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @module: amd
2+
// @moduleResolution: node
3+
// @outFile: out/output.js
4+
// @fullEmitPaths: true
5+
// @resolveJsonModule: true
6+
7+
// @Filename: file1.ts
8+
import * as b from './b.json';
9+
10+
// @Filename: b.json
11+
{
12+
"a": true,
13+
"b": "hello"
14+
}

0 commit comments

Comments
 (0)