Skip to content

Commit dd0ed44

Browse files
author
David Sheldrick
committed
Add option to output .js files while preserving jsx
This commit adds the ability to preserve jsx in source code, but also to output .js files rather than .jsx files. This is useful for react-native which does not support .jsx files.
1 parent 3cf326a commit dd0ed44

File tree

9 files changed

+125
-13
lines changed

9 files changed

+125
-13
lines changed

lib/protocol.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,9 +1798,10 @@ declare namespace ts.server.protocol {
17981798
namespace JsxEmit {
17991799
type None = "None";
18001800
type Preserve = "Preserve";
1801+
type PreserveWithJsExtension = "PreserveWithJsExtension";
18011802
type React = "React";
18021803
}
1803-
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
1804+
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension;
18041805
namespace ModuleKind {
18051806
type None = "None";
18061807
type CommonJS = "CommonJS";
@@ -1880,4 +1881,4 @@ declare namespace ts {
18801881
}
18811882
import protocol = ts.server.protocol;
18821883
export = protocol;
1883-
export as namespace protocol;
1884+
export as namespace protocol;

src/compiler/commandLineParser.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ namespace ts {
6767
name: "jsx",
6868
type: createMapFromTemplate({
6969
"preserve": JsxEmit.Preserve,
70+
"preservewithjsextension": JsxEmit.PreserveWithJsExtension,
7071
"react": JsxEmit.React
7172
}),
7273
paramType: Diagnostics.KIND,
73-
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
74+
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_preserveWithJsExtension_or_react,
7475
},
7576
{
7677
name: "reactNamespace",

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2713,7 +2713,7 @@
27132713
"category": "Message",
27142714
"code": 6079
27152715
},
2716-
"Specify JSX code generation: 'preserve' or 'react'": {
2716+
"Specify JSX code generation: 'preserve', 'preserveWithJsExtension', or 'react'": {
27172717
"category": "Message",
27182718
"code": 6080
27192719
},

src/compiler/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3298,7 +3298,8 @@
32983298
export const enum JsxEmit {
32993299
None = 0,
33003300
Preserve = 1,
3301-
React = 2
3301+
React = 2,
3302+
PreserveWithJsExtension = 3
33023303
}
33033304

33043305
export const enum NewLineKind {

src/harness/unittests/commandLineParsing.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace ts {
8787
start: undefined,
8888
length: undefined,
8989
}, {
90-
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
90+
messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'",
9191
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
9292
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
9393

src/harness/unittests/convertCompilerOptionsFromJson.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ namespace ts {
9494
file: undefined,
9595
start: 0,
9696
length: 0,
97-
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
97+
messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'",
9898
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
9999
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
100100
}]

src/harness/unittests/matchFiles.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,31 @@ namespace ts {
909909
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
910910
assertParsed(actual, expected);
911911
});
912+
it("with jsx=preserveWithJsExtension, allowJs=false", () => {
913+
const json = {
914+
compilerOptions: {
915+
jsx: "preserveWithJsExtension",
916+
allowJs: false
917+
}
918+
};
919+
const expected: ts.ParsedCommandLine = {
920+
options: {
921+
jsx: ts.JsxEmit.PreserveWithJsExtension,
922+
allowJs: false
923+
},
924+
errors: [],
925+
fileNames: [
926+
"c:/dev/a.ts",
927+
"c:/dev/b.tsx",
928+
"c:/dev/c.tsx",
929+
],
930+
wildcardDirectories: {
931+
"c:/dev": ts.WatchDirectoryFlags.Recursive
932+
}
933+
};
934+
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
935+
assertParsed(actual, expected);
936+
});
912937
it("with jsx=none, allowJs=true", () => {
913938
const json = {
914939
compilerOptions: {
@@ -961,6 +986,33 @@ namespace ts {
961986
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
962987
assertParsed(actual, expected);
963988
});
989+
it("with jsx=preserveWithJsExtension, allowJs=true", () => {
990+
const json = {
991+
compilerOptions: {
992+
jsx: "preserveWithJsExtension",
993+
allowJs: true
994+
}
995+
};
996+
const expected: ts.ParsedCommandLine = {
997+
options: {
998+
jsx: ts.JsxEmit.PreserveWithJsExtension,
999+
allowJs: true
1000+
},
1001+
errors: [],
1002+
fileNames: [
1003+
"c:/dev/a.ts",
1004+
"c:/dev/b.tsx",
1005+
"c:/dev/c.tsx",
1006+
"c:/dev/d.js",
1007+
"c:/dev/e.jsx",
1008+
],
1009+
wildcardDirectories: {
1010+
"c:/dev": ts.WatchDirectoryFlags.Recursive
1011+
}
1012+
};
1013+
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
1014+
assertParsed(actual, expected);
1015+
});
9641016
it("exclude .min.js files using wildcards", () => {
9651017
const json = {
9661018
compilerOptions: {
@@ -1306,4 +1358,4 @@ namespace ts {
13061358
});
13071359
});
13081360
});
1309-
}
1361+
}

src/server/protocol.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ namespace ts.server.protocol {
417417
startOffset: number;
418418

419419
/**
420-
* Position (can be specified instead of line/offset pair)
420+
* Position (can be specified instead of line/offset pair)
421421
*/
422422
/* @internal */
423423
startPosition?: number;
@@ -433,7 +433,7 @@ namespace ts.server.protocol {
433433
endOffset: number;
434434

435435
/**
436-
* Position (can be specified instead of line/offset pair)
436+
* Position (can be specified instead of line/offset pair)
437437
*/
438438
/* @internal */
439439
endPosition?: number;
@@ -445,7 +445,7 @@ namespace ts.server.protocol {
445445
}
446446

447447
/**
448-
* Response for GetCodeFixes request.
448+
* Response for GetCodeFixes request.
449449
*/
450450
export interface GetCodeFixesResponse extends Response {
451451
body?: CodeAction[];
@@ -2272,10 +2272,11 @@ namespace ts.server.protocol {
22722272
export namespace JsxEmit {
22732273
export type None = "None";
22742274
export type Preserve = "Preserve";
2275+
export type PreserveWithJsExtension = "PreserveWithJsExtension";
22752276
export type React = "React";
22762277
}
22772278

2278-
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
2279+
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension;
22792280

22802281
export namespace ModuleKind {
22812282
export type None = "None";

tests/cases/unittests/matchFiles.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,33 @@ namespace ts {
898898
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
899899
assert.deepEqual(actual.errors, expected.errors);
900900
});
901+
it("with jsx=preserveWithJsExtension, allowJs=false", () => {
902+
const json = {
903+
compilerOptions: {
904+
jsx: "preserveWithJsExtension",
905+
allowJs: false
906+
}
907+
};
908+
const expected: ts.ParsedCommandLine = {
909+
options: {
910+
jsx: ts.JsxEmit.PreserveWithJsExtension,
911+
allowJs: false
912+
},
913+
errors: [],
914+
fileNames: [
915+
"c:/dev/a.ts",
916+
"c:/dev/b.tsx",
917+
"c:/dev/c.tsx",
918+
],
919+
wildcardDirectories: {
920+
"c:/dev": ts.WatchDirectoryFlags.Recursive
921+
}
922+
};
923+
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
924+
assert.deepEqual(actual.fileNames, expected.fileNames);
925+
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
926+
assert.deepEqual(actual.errors, expected.errors);
927+
});
901928
it("with jsx=none, allowJs=true", () => {
902929
const json = {
903930
compilerOptions: {
@@ -954,6 +981,35 @@ namespace ts {
954981
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
955982
assert.deepEqual(actual.errors, expected.errors);
956983
});
984+
it("with jsx=preserveWithJsExtension, allowJs=true", () => {
985+
const json = {
986+
compilerOptions: {
987+
jsx: "preserveWithJsExtension",
988+
allowJs: true
989+
}
990+
};
991+
const expected: ts.ParsedCommandLine = {
992+
options: {
993+
jsx: ts.JsxEmit.PreserveWithJsExtension,
994+
allowJs: true
995+
},
996+
errors: [],
997+
fileNames: [
998+
"c:/dev/a.ts",
999+
"c:/dev/b.tsx",
1000+
"c:/dev/c.tsx",
1001+
"c:/dev/d.js",
1002+
"c:/dev/e.jsx",
1003+
],
1004+
wildcardDirectories: {
1005+
"c:/dev": ts.WatchDirectoryFlags.Recursive
1006+
}
1007+
};
1008+
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
1009+
assert.deepEqual(actual.fileNames, expected.fileNames);
1010+
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
1011+
assert.deepEqual(actual.errors, expected.errors);
1012+
});
9571013
describe("with trailing recursive directory", () => {
9581014
it("in includes", () => {
9591015
const json = {
@@ -1149,4 +1205,4 @@ namespace ts {
11491205
});
11501206
});
11511207
});
1152-
}
1208+
}

0 commit comments

Comments
 (0)