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.
This commit is contained in:
David Sheldrick 2017-01-23 17:40:20 +01:00
parent 3cf326a8c4
commit dd0ed44b9a
9 changed files with 125 additions and 13 deletions

5
lib/protocol.d.ts vendored
View File

@ -1798,9 +1798,10 @@ declare namespace ts.server.protocol {
namespace JsxEmit {
type None = "None";
type Preserve = "Preserve";
type PreserveWithJsExtension = "PreserveWithJsExtension";
type React = "React";
}
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension;
namespace ModuleKind {
type None = "None";
type CommonJS = "CommonJS";
@ -1880,4 +1881,4 @@ declare namespace ts {
}
import protocol = ts.server.protocol;
export = protocol;
export as namespace protocol;
export as namespace protocol;

View File

@ -67,10 +67,11 @@ namespace ts {
name: "jsx",
type: createMapFromTemplate({
"preserve": JsxEmit.Preserve,
"preservewithjsextension": JsxEmit.PreserveWithJsExtension,
"react": JsxEmit.React
}),
paramType: Diagnostics.KIND,
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_preserveWithJsExtension_or_react,
},
{
name: "reactNamespace",

View File

@ -2713,7 +2713,7 @@
"category": "Message",
"code": 6079
},
"Specify JSX code generation: 'preserve' or 'react'": {
"Specify JSX code generation: 'preserve', 'preserveWithJsExtension', or 'react'": {
"category": "Message",
"code": 6080
},

View File

@ -3298,7 +3298,8 @@
export const enum JsxEmit {
None = 0,
Preserve = 1,
React = 2
React = 2,
PreserveWithJsExtension = 3
}
export const enum NewLineKind {

View File

@ -87,7 +87,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,

View File

@ -94,7 +94,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]

View File

@ -909,6 +909,31 @@ namespace ts {
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("with jsx=preserveWithJsExtension, allowJs=false", () => {
const json = {
compilerOptions: {
jsx: "preserveWithJsExtension",
allowJs: false
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.PreserveWithJsExtension,
allowJs: false
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("with jsx=none, allowJs=true", () => {
const json = {
compilerOptions: {
@ -961,6 +986,33 @@ namespace ts {
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("with jsx=preserveWithJsExtension, allowJs=true", () => {
const json = {
compilerOptions: {
jsx: "preserveWithJsExtension",
allowJs: true
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.PreserveWithJsExtension,
allowJs: true
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
"c:/dev/d.js",
"c:/dev/e.jsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("exclude .min.js files using wildcards", () => {
const json = {
compilerOptions: {
@ -1306,4 +1358,4 @@ namespace ts {
});
});
});
}
}

View File

@ -417,7 +417,7 @@ namespace ts.server.protocol {
startOffset: number;
/**
* Position (can be specified instead of line/offset pair)
* Position (can be specified instead of line/offset pair)
*/
/* @internal */
startPosition?: number;
@ -433,7 +433,7 @@ namespace ts.server.protocol {
endOffset: number;
/**
* Position (can be specified instead of line/offset pair)
* Position (can be specified instead of line/offset pair)
*/
/* @internal */
endPosition?: number;
@ -445,7 +445,7 @@ namespace ts.server.protocol {
}
/**
* Response for GetCodeFixes request.
* Response for GetCodeFixes request.
*/
export interface GetCodeFixesResponse extends Response {
body?: CodeAction[];
@ -2272,10 +2272,11 @@ namespace ts.server.protocol {
export namespace JsxEmit {
export type None = "None";
export type Preserve = "Preserve";
export type PreserveWithJsExtension = "PreserveWithJsExtension";
export type React = "React";
}
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension;
export namespace ModuleKind {
export type None = "None";

View File

@ -898,6 +898,33 @@ namespace ts {
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
it("with jsx=preserveWithJsExtension, allowJs=false", () => {
const json = {
compilerOptions: {
jsx: "preserveWithJsExtension",
allowJs: false
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.PreserveWithJsExtension,
allowJs: false
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
it("with jsx=none, allowJs=true", () => {
const json = {
compilerOptions: {
@ -954,6 +981,35 @@ namespace ts {
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
it("with jsx=preserveWithJsExtension, allowJs=true", () => {
const json = {
compilerOptions: {
jsx: "preserveWithJsExtension",
allowJs: true
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.PreserveWithJsExtension,
allowJs: true
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
"c:/dev/d.js",
"c:/dev/e.jsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
describe("with trailing recursive directory", () => {
it("in includes", () => {
const json = {
@ -1149,4 +1205,4 @@ namespace ts {
});
});
});
}
}