Skip to content

Commit e8665f4

Browse files
committed
New TransformAndSaveJsxFile method to transform JSX and save result into .generated.js file. Initial implementation of MSBuild task (references #5)
1 parent 113b1f2 commit e8665f4

21 files changed

+361
-15
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ src/**/*.nuspec
55
!src/template.nuspec
66
site/jekyll/_site
77
src/React.Sample.Cassette/cassette-cache
8+
*.generated.js
89

910
## Ignore Visual Studio temporary files, build results, and
1011
## files generated by popular Visual Studio add-ons.

src/Cassette.React/CassetteMSBuildStartup.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public void Start()
3333

3434
// All "per-request" registrations should be singletons in MSBuild, since there's no
3535
// such thing as a "request"
36-
// TODO: Should these be per-task instead, once non-Cassette MSBuild support
37-
// is introduced?
3836
Initializer.Initialize(requestLifetimeRegistration: registration => registration.AsSingleton());
3937
}
4038
}

src/Cassette.React/JsxCompiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public JsxCompiler(IReactEnvironment environment)
3636
/// <returns>JavaScript</returns>
3737
public CompileResult Compile(string source, CompileContext context)
3838
{
39-
var output = _environment.TransformJsx(source);
39+
var output = _environment.JsxTransformer.TransformJsx(source);
4040
return new CompileResult(output, Enumerable.Empty<string>());
4141
}
4242
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2014, 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 React.TinyIoC;
11+
12+
namespace React.MSBuild
13+
{
14+
/// <summary>
15+
/// Handles registration of ReactJS.NET components that are only applicable
16+
/// when used with MSBuild
17+
/// </summary>
18+
public class AssemblyRegistration : IAssemblyRegistration
19+
{
20+
/// <summary>
21+
/// Registers components in the React IoC container
22+
/// </summary>
23+
/// <param name="container">Container to register components in</param>
24+
public void Register(TinyIoCContainer container)
25+
{
26+
container.Register<ICache, NullCache>();
27+
container.Register<IFileSystem, SimpleFileSystem>();
28+
}
29+
}
30+
}

src/React.MSBuild/MSBuildHost.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2014, 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 System;
11+
12+
namespace React.MSBuild
13+
{
14+
/// <summary>
15+
/// Handles initialisation of the MSBuild environment.
16+
/// </summary>
17+
internal static class MSBuildHost
18+
{
19+
/// <summary>
20+
/// Hack to use Lazy{T} for thread-safe, once-off initialisation :)
21+
/// </summary>
22+
private readonly static Lazy<bool> _initializer = new Lazy<bool>(Initialize);
23+
24+
/// <summary>
25+
/// Ensures the environment has been initialised.
26+
/// </summary>
27+
public static bool EnsureInitialized()
28+
{
29+
return _initializer.Value;
30+
}
31+
32+
/// <summary>
33+
/// Actually perform the initialisation of the environment.
34+
/// </summary>
35+
/// <returns></returns>
36+
private static bool Initialize()
37+
{
38+
// All "per-request" registrations should be singletons in MSBuild, since there's no
39+
// such thing as a "request"
40+
Initializer.Initialize(requestLifetimeRegistration: registration => registration.AsSingleton());
41+
42+
return true;
43+
}
44+
}
45+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2014, 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 System.Reflection;
11+
using System.Runtime.InteropServices;
12+
13+
[assembly: AssemblyTitle("React.MSBuild")]
14+
[assembly: AssemblyDescription("MSBuild integration for ReactJS.NET")]
15+
[assembly: ComVisible(false)]
16+
[assembly: Guid("6b314671-5ea3-47ea-bdd8-7d75b1b1d9fa")]
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{AF531A37-B93F-4113-9C2C-4DB28064B926}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>React.MSBuild</RootNamespace>
11+
<AssemblyName>React.MSBuild</AssemblyName>
12+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
</PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16+
<DebugSymbols>true</DebugSymbols>
17+
<DebugType>full</DebugType>
18+
<Optimize>false</Optimize>
19+
<OutputPath>..\..\bin\Debug\React.MSBuild\</OutputPath>
20+
<DefineConstants>DEBUG;TRACE</DefineConstants>
21+
<ErrorReport>prompt</ErrorReport>
22+
<WarningLevel>4</WarningLevel>
23+
<NoWarn>1607</NoWarn>
24+
<DocumentationFile>..\..\bin\Debug\React.MSBuild\React.MSBuild.XML</DocumentationFile>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<DebugType>pdbonly</DebugType>
28+
<Optimize>true</Optimize>
29+
<OutputPath>..\..\bin\Release\React.MSBuild\</OutputPath>
30+
<DefineConstants>TRACE</DefineConstants>
31+
<ErrorReport>prompt</ErrorReport>
32+
<WarningLevel>4</WarningLevel>
33+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
34+
<NoWarn>1607</NoWarn>
35+
<DocumentationFile>..\..\bin\Release\React.MSBuild\React.MSBuild.XML</DocumentationFile>
36+
</PropertyGroup>
37+
<ItemGroup>
38+
<Reference Include="Microsoft.Build.Framework" />
39+
<Reference Include="Microsoft.Build.Utilities.v4.0" />
40+
<Reference Include="System" />
41+
<Reference Include="System.Core" />
42+
<Reference Include="Microsoft.CSharp" />
43+
</ItemGroup>
44+
<ItemGroup>
45+
<Compile Include="..\SharedAssemblyInfo.cs">
46+
<Link>Properties\SharedAssemblyInfo.cs</Link>
47+
</Compile>
48+
<Compile Include="..\SharedAssemblyVersionInfo.cs">
49+
<Link>Properties\SharedAssemblyVersionInfo.cs</Link>
50+
</Compile>
51+
<Compile Include="AssemblyRegistration.cs" />
52+
<Compile Include="MSBuildHost.cs" />
53+
<Compile Include="Properties\AssemblyInfo.cs" />
54+
<Compile Include="TransformJsx.cs" />
55+
</ItemGroup>
56+
<ItemGroup>
57+
<ProjectReference Include="..\React\React.csproj">
58+
<Project>{d0cc8a22-cee6-485c-924b-1f94426fea59}</Project>
59+
<Name>React</Name>
60+
</ProjectReference>
61+
</ItemGroup>
62+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
63+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
64+
Other similar extension points exist, see Microsoft.Common.targets.
65+
<Target Name="BeforeBuild">
66+
</Target>
67+
<Target Name="AfterBuild">
68+
</Target>
69+
-->
70+
</Project>

src/React.MSBuild/TransformJsx.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2014, 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 System.Diagnostics;
11+
using System.IO;
12+
using Microsoft.Build.Framework;
13+
using Microsoft.Build.Utilities;
14+
15+
namespace React.MSBuild
16+
{
17+
/// <summary>
18+
/// MSBuild task that handles transforming JSX to JavaScript
19+
/// </summary>
20+
public class TransformJsx : Task
21+
{
22+
/// <summary>
23+
/// The ReactJS.NET environment
24+
/// </summary>
25+
private IReactEnvironment _environment;
26+
27+
/// <summary>
28+
/// Directory to process JSX files in. All subdirectories will be searched.
29+
/// </summary>
30+
[Required]
31+
public string SourceDir { get; set; }
32+
33+
/// <summary>
34+
/// Executes the task.
35+
/// </summary>
36+
/// <returns><c>true</c> on success</returns>
37+
public override bool Execute()
38+
{
39+
MSBuildHost.EnsureInitialized();
40+
_environment = React.AssemblyRegistration.Container.Resolve<IReactEnvironment>();
41+
42+
Log.LogMessage("Starting TransformJsx");
43+
var stopwatch = Stopwatch.StartNew();
44+
var result = ExecuteInternal();
45+
Log.LogMessage("TransformJsx completed in {0}", stopwatch.Elapsed);
46+
return result;
47+
}
48+
49+
/// <summary>
50+
/// The core of the task. Locates all JSX files and transforms them to JavaScript.
51+
/// </summary>
52+
/// <returns><c>true</c> on success</returns>
53+
private bool ExecuteInternal()
54+
{
55+
var files = Directory.EnumerateFiles(SourceDir, "*.jsx", SearchOption.AllDirectories);
56+
foreach (var path in files)
57+
{
58+
var relativePath = path.Substring(SourceDir.Length + 1);
59+
Log.LogMessage(" -> Processing {0}", relativePath);
60+
_environment.JsxTransformer.TransformAndSaveJsxFile(path);
61+
}
62+
63+
return true;
64+
}
65+
}
66+
}

src/React.Sample.Mvc4/React.Sample.Mvc4.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@
162162
<ItemGroup>
163163
<Content Include="Content\Sample.jsx" />
164164
</ItemGroup>
165+
<ItemGroup>
166+
<Content Include="TransformJsx.proj" />
167+
</ItemGroup>
165168
<PropertyGroup>
166169
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
167170
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
@@ -172,6 +175,11 @@
172175
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
173176
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
174177
</Target>
178+
<Target Name="TransformJsx" AfterTargets="AfterBuild">
179+
<!-- This needs to be ran via Exec since the build locks the React.MSBuild.dll file -->
180+
<!-- In a regular project, you could just call this task directly -->
181+
<Exec Command="&quot;$(msbuildtoolspath)\msbuild.exe&quot; TransformJsx.proj /nr:false /p:Configuration=$(Configuration)" />
182+
</Target>
175183
<ProjectExtensions>
176184
<VisualStudio>
177185
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="TransformJsx">
3+
<UsingTask AssemblyFile="..\..\bin\$(Configuration)\React.MSBuild\React.MSBuild.dll" TaskName="TransformJsx" />
4+
<Target Name="TransformJsx">
5+
<TransformJsx SourceDir="$(MSBuildProjectDirectory)" />
6+
</Target>
7+
</Project>

0 commit comments

Comments
 (0)