Skip to content

Commit 2ca1cd0

Browse files
TorbenRahbekKochDaniel15
authored andcommitted
Use file hash to check for file changes before transpiling (#299) (#313)
* Use file hash to check for file changes before transpiling (#299) * Add .editorconfig file * Add check for file hash check (#299) * Remove debug File.WriteAllText from test. * Fix erroneous comment in babel.cs
1 parent 9be0021 commit 2ca1cd0

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

src/.editorconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
end_of_line = crlf
7+
indent_size = 4
8+
indent_style = tab
9+
insert_final_newline = true
10+
11+
[*.json]
12+
indent_size = 2
13+
indent_style = space

src/React.Core/Babel.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,37 @@ string filename
350350
)
351351
{
352352
var outputPath = GetOutputPath(filename);
353-
var sourceMapPath = GetSourceMapOutputPath(filename);
354353
var contents = _fileSystem.ReadAsString(filename);
354+
if (CacheIsValid(contents, outputPath))
355+
return outputPath;
356+
355357
var result = TransformWithHeader(filename, contents, null);
358+
359+
var sourceMapPath = GetSourceMapOutputPath(filename);
356360
_fileSystem.WriteAsString(outputPath, result.Code);
357-
_fileSystem.WriteAsString(sourceMapPath, result.SourceMap == null ? string.Empty : result.SourceMap.ToJson());
361+
_fileSystem.WriteAsString(sourceMapPath, result.SourceMap == null ? string.Empty : result.SourceMap.ToJson());
362+
358363
return outputPath;
359364
}
365+
366+
/// <summary>
367+
/// Checks whether an input file (given as inputFileContents) should be transpiled
368+
/// by calculating the hash and comparing it to the hash value stored
369+
/// in the file given by outputPath. If the outputPath file does not
370+
/// exist the input file should always be transpiled.
371+
/// </summary>
372+
/// <param name="inputFileContents">The contents of the input file.</param>
373+
/// <param name="outputPath">The output path of the (possibly previously) generated file.</param>
374+
/// <returns>Returns false if the file should be transpiled, true otherwise.</returns>
375+
public virtual bool CacheIsValid(string inputFileContents, string outputPath)
376+
{
377+
if (!_fileSystem.FileExists(outputPath))
378+
return false;
379+
380+
var hashForInputFile = _fileCacheHash.CalculateHash(inputFileContents);
381+
var existingOutputContents = _fileSystem.ReadAsString(outputPath);
382+
var fileHasNotChanged = _fileCacheHash.ValidateHash(existingOutputContents, hashForInputFile);
383+
return fileHasNotChanged;
384+
}
360385
}
361386
}

src/React.Tests/Core/BabelTransformerTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public void SetUp()
3232
_fileSystem = new Mock<IFileSystem>();
3333
_fileSystem.Setup(x => x.MapPath(It.IsAny<string>())).Returns<string>(x => x);
3434

35+
// Per default the output file should not exist, then individual tests
36+
// can choose otherwise.
37+
_fileSystem.Setup(x => x.FileExists(It.IsAny<string>())).Returns(false);
38+
3539
_fileCacheHash = new Mock<IFileCacheHash>();
3640

3741
_babel = new Babel(
@@ -152,6 +156,29 @@ public void ShouldSaveTransformationResult()
152156
StringAssert.EndsWith("React.DOM.div('Hello World')", result);
153157
}
154158

159+
[Test]
160+
public void ShouldSkipTransformationIfCacheIsValid()
161+
{
162+
_fileSystem.Setup(x => x.ReadAsString("foo.jsx")).Returns("<div>Hello World</div>");
163+
_fileSystem.Setup(x => x.FileExists(It.IsAny<string>())).Returns(true);
164+
_fileCacheHash.Setup(x => x.ValidateHash(It.IsAny<string>(), It.IsAny<string>())).Returns(true);
165+
_environment.Setup(x => x.ExecuteWithBabel<JavaScriptWithSourceMap>(
166+
"ReactNET_transform_sourcemap",
167+
It.IsAny<string>(),
168+
It.IsAny<string>(), // Babel config
169+
"foo.jsx" // File name
170+
)).Returns(new JavaScriptWithSourceMap { Code = "React.DOM.div('Hello World')" });
171+
172+
string result = null;
173+
_fileSystem.Setup(x => x.WriteAsString("foo.generated.js", It.IsAny<string>())).Callback(
174+
(string filename, string contents) => result = contents
175+
);
176+
177+
var resultFilename = _babel.TransformAndSaveFile("foo.jsx");
178+
Assert.AreEqual("foo.generated.js", resultFilename);
179+
Assert.IsNull(result, "There should be no result. Cached result should have been used.");
180+
}
181+
155182
private void SetUpEmptyCache()
156183
{
157184
_cache.Setup(x => x.Get<JavaScriptWithSourceMap>("JSX_v3_foo.jsx", null)).Returns((JavaScriptWithSourceMap)null);

0 commit comments

Comments
 (0)