Skip to content

Commit ddba6d8

Browse files
authored
Merge pull request #26825 from Microsoft/resolveJsonModuleEmit
Support json module emit when module emit is commonjs, amd, es2015 or esnext
2 parents 8b30ff8 + e41dbcd commit ddba6d8

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
@@ -2275,7 +2275,7 @@ namespace ts {
22752275
else if (!compilerOptions.resolveJsonModule &&
22762276
fileExtensionIs(moduleReference, Extension.Json) &&
22772277
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs &&
2278-
getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) {
2278+
hasJsonModuleEmitEnabled(compilerOptions)) {
22792279
error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference);
22802280
}
22812281
else {

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2912,7 +2912,7 @@
29122912
"category": "Error",
29132913
"code": 5070
29142914
},
2915-
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": {
2915+
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.": {
29162916
"category": "Error",
29172917
"code": 5071
29182918
},

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
@@ -7033,6 +7033,18 @@ namespace ts {
70337033
return moduleResolution;
70347034
}
70357035

7036+
export function hasJsonModuleEmitEnabled(options: CompilerOptions) {
7037+
switch (getEmitModuleKind(options)) {
7038+
case ModuleKind.CommonJS:
7039+
case ModuleKind.AMD:
7040+
case ModuleKind.ES2015:
7041+
case ModuleKind.ESNext:
7042+
return true;
7043+
default:
7044+
return false;
7045+
}
7046+
}
7047+
70367048
export function unreachableCodeIsError(options: CompilerOptions): boolean {
70377049
return options.allowUnreachableCode === false;
70387050
}

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+
}

0 commit comments

Comments
 (0)