Skip to content

Commit a228cda

Browse files
committedOct 11, 2015
Allow configuration of Babel, and pass file name. Closes #167 and #138
1 parent 070b201 commit a228cda

11 files changed

+195
-19
lines changed
 

Diff for: ‎src/Cassette.React/JsxCompiler.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* of patent rights can be found in the PATENTS file in the same directory.
88
*/
99

10+
using System.IO;
1011
using System.Linq;
1112
using React;
1213

@@ -36,7 +37,10 @@ public JsxCompiler(IReactEnvironment environment)
3637
/// <returns>JavaScript</returns>
3738
public CompileResult Compile(string source, CompileContext context)
3839
{
39-
var output = _environment.JsxTransformer.TransformJsx(source);
40+
var output = _environment.JsxTransformer.TransformJsx(
41+
source,
42+
Path.GetFileName(context.SourceFilePath)
43+
);
4044
return new CompileResult(output, Enumerable.Empty<string>());
4145
}
4246
}

Diff for: ‎src/React.Core/BabelConfig.cs

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace React
5+
{
6+
/// <summary>
7+
/// Configuration for Babel (see http://babeljs.io/docs/usage/options/ for detailed
8+
/// documentation).
9+
/// </summary>
10+
public class BabelConfig
11+
{
12+
/// <summary>
13+
/// Gets or sets whether Babel's "loose mode" is used for all transformers. See
14+
/// http://babeljs.io/docs/advanced/loose/ for more information. Only one of
15+
/// <see cref="AllLoose"/> or <see cref="Loose"/> can be used at a time.
16+
/// </summary>
17+
public bool AllLoose { get; set; }
18+
19+
/// <summary>
20+
/// Gets or sets whether Babel should use a reference to babelHelpers instead of placing
21+
/// helpers at the top of your code. Meant to be used in conjunction with external
22+
/// helpers (http://babeljs.io/docs/advanced/external-helpers/)
23+
/// </summary>
24+
public bool ExternalHelpers { get; set; }
25+
26+
/// <summary>
27+
/// Gets or sets the transformers to use in Babel's "loose mode". See
28+
/// http://babeljs.io/docs/advanced/loose/ for more information. Only one of
29+
/// <see cref="AllLoose"/> or <see cref="Loose"/> can be used at a time.
30+
/// </summary>
31+
public IEnumerable<string> Loose { get; set; }
32+
33+
/// <summary>
34+
/// Gets or sets an transformers to optionally use. See
35+
/// http://babeljs.io/docs/advanced/transformers/#optional for a full list of transformers
36+
/// </summary>
37+
public IEnumerable<string> Optional { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets the experimental proposal stage (http://babeljs.io/docs/usage/experimental/).
41+
/// </summary>
42+
public int Stage { get; set; }
43+
44+
/// <summary>
45+
/// Creates a new instance of <see cref="BabelConfig" />.
46+
/// </summary>
47+
public BabelConfig()
48+
{
49+
Stage = 2;
50+
}
51+
52+
/// <summary>
53+
/// Serializes this Babel configuration into the format required for Babel.
54+
/// </summary>
55+
/// <returns></returns>
56+
public string Serialize()
57+
{
58+
var config = new Dictionary<string, object>
59+
{
60+
{"externalHelpers", ExternalHelpers},
61+
{"optional", Optional},
62+
{"stage", Stage},
63+
};
64+
if (AllLoose)
65+
{
66+
config.Add("loose", "all");
67+
}
68+
else if (Loose != null)
69+
{
70+
config.Add("loose", Loose);
71+
}
72+
return JsonConvert.SerializeObject(config);
73+
}
74+
}
75+
}

Diff for: ‎src/React.Core/IJsxTransformer.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,18 @@ JavaScriptWithSourceMap TransformJsxFileWithSourceMap(
4141
/// <see cref="TransformJsxFile"/> if loading from a file since this will cache the result.
4242
/// </summary>
4343
/// <param name="input">JSX</param>
44+
/// <param name="filename">Name of the file being transformed</param>
4445
/// <returns>JavaScript</returns>
45-
string TransformJsx(string input);
46-
46+
string TransformJsx(string input, string filename = "unknown");
47+
4748
/// <summary>
4849
/// Transforms JSX to regular JavaScript and also returns a source map to map the compiled
4950
/// source to the original version. The result is not cached.
5051
/// </summary>
5152
/// <param name="input">JSX</param>
53+
/// <param name="filename">Name of the file being transformed</param>
5254
/// <returns>JavaScript and source map</returns>
53-
JavaScriptWithSourceMap TransformJsxWithSourceMap(string input);
55+
JavaScriptWithSourceMap TransformJsxWithSourceMap(string input, string filename = "unknown");
5456

5557
/// <summary>
5658
/// Transforms a JSX file to JavaScript, and saves the result into a ".generated.js" file

Diff for: ‎src/React.Core/IReactSiteConfiguration.cs

+10
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,15 @@ public interface IReactSiteConfiguration
122122
/// </summary>
123123
/// <returns>The configuration, for chaining</returns>
124124
IReactSiteConfiguration SetLoadReact(bool loadReact);
125+
126+
/// <summary>
127+
/// Gets or sets the Babel configuration to use.
128+
/// </summary>
129+
BabelConfig BabelConfig { get; set; }
130+
/// <summary>
131+
/// Sets the Babel configuration to use.
132+
/// </summary>
133+
/// <returns>The configuration, for chaining</returns>
134+
IReactSiteConfiguration SetBabelConfig(BabelConfig value);
125135
}
126136
}

Diff for: ‎src/React.Core/JsxTransformer.cs

+18-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
using System;
11+
using System.Collections.Generic;
1112
using System.Diagnostics;
1213
using System.IO;
1314
using React.Exceptions;
@@ -56,6 +57,10 @@ public class JsxTransformer : IJsxTransformer
5657
/// Site-wide configuration
5758
/// </summary>
5859
protected readonly IReactSiteConfiguration _config;
60+
/// <summary>
61+
/// The serialized Babel configuration
62+
/// </summary>
63+
protected readonly string _babelConfig;
5964

6065
/// <summary>
6166
/// Initializes a new instance of the <see cref="JsxTransformer"/> class.
@@ -72,6 +77,7 @@ public JsxTransformer(IReactEnvironment environment, ICache cache, IFileSystem f
7277
_fileSystem = fileSystem;
7378
_fileCacheHash = fileCacheHash;
7479
_config = siteConfig;
80+
_babelConfig = siteConfig.BabelConfig.Serialize();
7581
}
7682

7783
/// <summary>
@@ -223,7 +229,7 @@ protected virtual JavaScriptWithSourceMap TransformJsxWithHeader(
223229
hash = _fileCacheHash.CalculateHash(contents);
224230
}
225231
var header = GetFileHeader(hash);
226-
var result = TransformJsxWithSourceMap(header + contents);
232+
var result = TransformJsxWithSourceMap(header + contents, filename);
227233
result.Hash = hash;
228234
if (result.SourceMap != null)
229235
{
@@ -243,14 +249,17 @@ protected virtual JavaScriptWithSourceMap TransformJsxWithHeader(
243249
/// <see cref="TransformJsxFile"/> if loading from a file since this will cache the result.
244250
/// </summary>
245251
/// <param name="input">JSX</param>
252+
/// <param name="filename">Name of the file being transformed</param>
246253
/// <returns>JavaScript</returns>
247-
public virtual string TransformJsx(string input)
254+
public virtual string TransformJsx(string input, string filename = "unknown")
248255
{
249256
try
250257
{
251258
var output = _environment.ExecuteWithLargerStackIfRequired<string>(
252259
"ReactNET_transform",
253-
input
260+
input,
261+
_babelConfig,
262+
filename
254263
);
255264
return output;
256265
}
@@ -265,16 +274,20 @@ public virtual string TransformJsx(string input)
265274
/// source to the original version. The result is not cached.
266275
/// </summary>
267276
/// <param name="input">JSX</param>
277+
/// <param name="filename">Name of the file being transformed</param>
268278
/// <returns>JavaScript and source map</returns>
269279
public virtual JavaScriptWithSourceMap TransformJsxWithSourceMap(
270-
string input
280+
string input,
281+
string filename = "unknown"
271282
)
272283
{
273284
try
274285
{
275286
return _environment.ExecuteWithLargerStackIfRequired<JavaScriptWithSourceMap>(
276287
"ReactNET_transform_sourcemap",
277-
input
288+
input,
289+
_babelConfig,
290+
filename
278291
);
279292
}
280293
catch (Exception ex)

Diff for: ‎src/React.Core/React.Core.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
<Link>Properties\SharedAssemblyVersionInfo.cs</Link>
9090
</Compile>
9191
<Compile Include="AssemblyRegistration.cs" />
92+
<Compile Include="BabelConfig.cs" />
9293
<Compile Include="Exceptions\ReactNotInitialisedException.cs" />
9394
<Compile Include="FileSystemExtensions.cs" />
9495
<Compile Include="JavaScriptEngineUtils.cs" />

Diff for: ‎src/React.Core/ReactSiteConfiguration.cs

+16
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static ReactSiteConfiguration()
3333
/// </summary>
3434
public ReactSiteConfiguration()
3535
{
36+
BabelConfig = new BabelConfig();
3637
ReuseJavaScriptEngines = true;
3738
AllowMsieEngine = true;
3839
LoadReact = true;
@@ -218,5 +219,20 @@ public IReactSiteConfiguration SetLoadReact(bool loadReact)
218219
LoadReact = loadReact;
219220
return this;
220221
}
222+
223+
/// <summary>
224+
/// Gets or sets the Babel configuration to use.
225+
/// </summary>
226+
public BabelConfig BabelConfig { get; set; }
227+
228+
/// <summary>
229+
/// Sets the Babel configuration to use.
230+
/// </summary>
231+
/// <returns>The configuration, for chaining</returns>
232+
public IReactSiteConfiguration SetBabelConfig(BabelConfig value)
233+
{
234+
BabelConfig = value;
235+
return this;
236+
}
221237
}
222238
}

Diff for: ‎src/React.Core/Resources/shims.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,23 @@ function ReactNET_initReact() {
6464
return false;
6565
}
6666

67-
function ReactNET_transform(input) {
67+
function ReactNET_transform(input, babelConfig, filename) {
68+
babelConfig = JSON.parse(babelConfig);
69+
babelConfig.filename = filename;
6870
try {
69-
return global.babel.transform(input).code;
71+
return global.babel.transform(input, babelConfig).code;
7072
} catch (ex) {
7173
// Parsing stack is extremely long and not very useful, so just rethrow the message.
7274
throw new Error(ex.message);
7375
}
7476
}
7577

76-
function ReactNET_transform_sourcemap(input) {
78+
function ReactNET_transform_sourcemap(input, babelConfig, filename) {
79+
babelConfig = JSON.parse(babelConfig);
80+
babelConfig.filename = filename;
81+
babelConfig.sourceMap = true;
7782
try {
78-
var result = global.babel.transform(input);
83+
var result = global.babel.transform(input, babelConfig);
7984
return JSON.stringify({
8085
code: result.code,
8186
sourceMap: result.map

Diff for: ‎src/React.Tests/Core/BabelConfigTests.cs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2015, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
using NUnit.Framework;
11+
12+
namespace React.Tests.Core
13+
{
14+
[TestFixture]
15+
public class BabelConfigTests
16+
{
17+
[Test]
18+
public void SerializesAllLoose()
19+
{
20+
var config = new BabelConfig
21+
{
22+
AllLoose = true,
23+
};
24+
var result = config.Serialize();
25+
Assert.AreEqual(@"{""externalHelpers"":false,""optional"":null,""stage"":2,""loose"":""all""}", result);
26+
}
27+
28+
[Test]
29+
public void SerializesSomeLoose()
30+
{
31+
var config = new BabelConfig
32+
{
33+
Loose = new[] { "foo" },
34+
};
35+
var result = config.Serialize();
36+
Assert.AreEqual(@"{""externalHelpers"":false,""optional"":null,""stage"":2,""loose"":[""foo""]}", result);
37+
}
38+
}
39+
}

Diff for: ‎src/React.Tests/Core/JsxTransformerTests.cs

+16-6
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ public void ShouldTransformJsx()
5252

5353
_environment.Verify(x => x.ExecuteWithLargerStackIfRequired<string>(
5454
"ReactNET_transform",
55-
"<div>Hello World</div>"
55+
"<div>Hello World</div>",
56+
It.IsAny<string>(),
57+
"unknown" // file name
5658
));
5759
}
5860

@@ -61,7 +63,9 @@ public void ShouldWrapExceptionsInJsxExeption()
6163
{
6264
_environment.Setup(x => x.ExecuteWithLargerStackIfRequired<string>(
6365
"ReactNET_transform",
64-
"<div>Hello World</div>"
66+
"<div>Hello World</div>",
67+
It.IsAny<string>(),
68+
"unknown" // file name
6569
)).Throws(new Exception("Something broke..."));
6670

6771
const string input = "<div>Hello World</div>";
@@ -102,7 +106,9 @@ public void ShouldTransformJsxIfFileCacheHashInvalid()
102106
_fileCacheHash.Setup(x => x.ValidateHash(It.IsAny<string>(), It.IsAny<string>())).Returns(false);
103107
_environment.Setup(x => x.ExecuteWithLargerStackIfRequired<JavaScriptWithSourceMap>(
104108
"ReactNET_transform_sourcemap",
105-
It.IsAny<string>()
109+
It.IsAny<string>(),
110+
It.IsAny<string>(), // Babel config
111+
"foo.jsx" // File name
106112
)).Returns(new JavaScriptWithSourceMap { Code = "React.DOM.div('Hello World')" });
107113

108114
var result = _jsxTransformer.TransformJsxFile("foo.jsx");
@@ -117,7 +123,9 @@ public void ShouldTransformJsxIfNoCache()
117123
_fileSystem.Setup(x => x.ReadAsString("foo.jsx")).Returns("<div>Hello World</div>");
118124
_environment.Setup(x => x.ExecuteWithLargerStackIfRequired<JavaScriptWithSourceMap>(
119125
"ReactNET_transform_sourcemap",
120-
It.IsAny<string>()
126+
It.IsAny<string>(),
127+
It.IsAny<string>(), // Babel config
128+
"foo.jsx" // File name
121129
)).Returns(new JavaScriptWithSourceMap { Code = "React.DOM.div('Hello World')" });
122130

123131
var result = _jsxTransformer.TransformJsxFile("foo.jsx");
@@ -130,7 +138,9 @@ public void ShouldSaveTransformationResult()
130138
_fileSystem.Setup(x => x.ReadAsString("foo.jsx")).Returns("<div>Hello World</div>");
131139
_environment.Setup(x => x.ExecuteWithLargerStackIfRequired<JavaScriptWithSourceMap>(
132140
"ReactNET_transform_sourcemap",
133-
It.IsAny<string>()
141+
It.IsAny<string>(),
142+
It.IsAny<string>(), // Babel config
143+
"foo.jsx" // File name
134144
)).Returns(new JavaScriptWithSourceMap { Code = "React.DOM.div('Hello World')" });
135145

136146
string result = null;
@@ -145,7 +155,7 @@ public void ShouldSaveTransformationResult()
145155

146156
private void SetUpEmptyCache()
147157
{
148-
_cache.Setup(x => x.Get<JavaScriptWithSourceMap>("JSX_v2_foo.jsx", null)).Returns((JavaScriptWithSourceMap)null);
158+
_cache.Setup(x => x.Get<JavaScriptWithSourceMap>("JSX_v3_foo.jsx", null)).Returns((JavaScriptWithSourceMap)null);
149159
}
150160
}
151161
}

Diff for: ‎src/React.Tests/React.Tests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
<Compile Include="..\SharedAssemblyVersionInfo.cs">
9696
<Link>Properties\SharedAssemblyVersionInfo.cs</Link>
9797
</Compile>
98+
<Compile Include="Core\BabelConfigTests.cs" />
9899
<Compile Include="Core\FileCacheHashTests.cs" />
99100
<Compile Include="Core\FileSystemBaseTests.cs" />
100101
<Compile Include="Core\FileSystemExtensionsTest.cs" />

0 commit comments

Comments
 (0)