Skip to content

Commit 5c0684f

Browse files
committed
Initial support for Cassette MSBuild compile-time bundle generation.
1 parent e79c4d8 commit 5c0684f

19 files changed

+358
-20
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ src/SharedAssemblyVersionInfo.cs
44
src/**/*.nuspec
55
!src/template.nuspec
66
site/jekyll/_site
7+
src/React.Sample.Cassette/cassette-cache
78

89
## Ignore Visual Studio temporary files, build results, and
910
## files generated by popular Visual Studio add-ons.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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;
11+
using React.TinyIoC;
12+
13+
namespace Cassette.React
14+
{
15+
/// <summary>
16+
/// Handles registration of ReactJS.NET components that are only applicable
17+
/// to Cassette when used in MSBuild.
18+
/// </summary>
19+
public class AssemblyRegistration : IAssemblyRegistration
20+
{
21+
/// <summary>
22+
/// Registers components in the React IoC container
23+
/// </summary>
24+
/// <param name="container">Container to register components in</param>
25+
public void Register(TinyIoCContainer container)
26+
{
27+
if (MSBuildUtils.IsInMSBuild())
28+
{
29+
RegisterForMSBuild(container);
30+
}
31+
}
32+
33+
/// <summary>
34+
/// Registers components specific to the MSBuild environment in the React IoC container.
35+
/// </summary>
36+
/// <param name="container">Container to register components in</param>
37+
private void RegisterForMSBuild(TinyIoCContainer container)
38+
{
39+
container.Register<ICache, NullCache>();
40+
container.Register<IFileSystem, SimpleFileSystem>();
41+
}
42+
}
43+
}

src/Cassette.React/Cassette.React.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,15 @@
5656
<Compile Include="..\SharedAssemblyVersionInfo.cs">
5757
<Link>Properties\SharedAssemblyVersionInfo.cs</Link>
5858
</Compile>
59+
<Compile Include="AssemblyRegistration.cs" />
60+
<Compile Include="CassetteMSBuildStartup.cs" />
5961
<Compile Include="InsertIntoPipelineJsxBundleProcessor.cs" />
6062
<Compile Include="JsxBundleProcessor.cs" />
6163
<Compile Include="JsxCompiler.cs" />
6264
<Compile Include="JsxFileSearchModifier.cs" />
65+
<Compile Include="MSBuildUtils.cs" />
6366
<Compile Include="Properties\AssemblyInfo.cs" />
67+
<Compile Include="ReactContainerConfiguration.cs" />
6468
</ItemGroup>
6569
<ItemGroup>
6670
<None Include="Cassette.React.nutrans" />
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
using System.Diagnostics;
12+
using React;
13+
14+
namespace Cassette.React
15+
{
16+
/// <summary>
17+
/// Cassette has two modes of operating - Web (ASP.NET) and MSBuild. IoC registration for web
18+
/// is already covered by React.Web. For the MSBuild mode, we need to initialise ReactJS.NET's
19+
/// IoC container here.
20+
/// </summary>
21+
public class CassetteMSBuildStartup : IStartUpTask
22+
{
23+
/// <summary>
24+
/// Handles initialisation of ReactJS.NET in Cassette. Only relevant when running in an
25+
/// MSBuild context.
26+
/// </summary>
27+
public void Start()
28+
{
29+
if (!MSBuildUtils.IsInMSBuild())
30+
{
31+
return;
32+
}
33+
34+
// All "per-request" registrations should be singletons in MSBuild, since there's no
35+
// such thing as a "request"
36+
// TODO: Should these be per-task instead, once non-Cassette MSBuild support
37+
// is introduced?
38+
Initializer.Initialize(requestLifetimeRegistration: registration => registration.AsSingleton());
39+
}
40+
}
41+
}

src/Cassette.React/JsxBundleProcessor.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System;
1111
using Cassette.BundleProcessing;
1212
using Cassette.Scripts;
13+
using React;
1314

1415
namespace Cassette.React
1516
{
@@ -20,14 +21,17 @@ namespace Cassette.React
2021
public class JsxBundleProcessor : IBundleProcessor<ScriptBundle>
2122
{
2223
private readonly CassetteSettings _settings;
24+
private readonly IReactEnvironment _environment;
2325

2426
/// <summary>
2527
/// Initializes a new instance of the <see cref="JsxBundleProcessor"/> class.
2628
/// </summary>
2729
/// <param name="settings">Cassette settings.</param>
28-
public JsxBundleProcessor(CassetteSettings settings)
30+
/// <param name="environment">The ReactJS.NET environment</param>
31+
public JsxBundleProcessor(CassetteSettings settings, IReactEnvironment environment)
2932
{
3033
_settings = settings;
34+
_environment = environment;
3135
}
3236

3337
/// <summary>
@@ -41,7 +45,7 @@ public void Process(ScriptBundle bundle)
4145
if (asset.Path.EndsWith(".jsx", StringComparison.InvariantCultureIgnoreCase))
4246
{
4347
asset.AddAssetTransformer(
44-
new CompileAsset(new JsxCompiler(), _settings.SourceDirectory)
48+
new CompileAsset(new JsxCompiler(_environment), _settings.SourceDirectory)
4549
);
4650
}
4751
}

src/Cassette.React/JsxCompiler.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ namespace Cassette.React
1717
/// </summary>
1818
public class JsxCompiler : ICompiler
1919
{
20+
private readonly IReactEnvironment _environment;
21+
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="JsxCompiler"/> class.
24+
/// </summary>
25+
/// <param name="environment">The ReactJS.NET environment</param>
26+
public JsxCompiler(IReactEnvironment environment)
27+
{
28+
_environment = environment;
29+
}
30+
2031
/// <summary>
2132
/// Compiles the specified JSX file into JavaScript
2233
/// </summary>
@@ -25,8 +36,7 @@ public class JsxCompiler : ICompiler
2536
/// <returns>JavaScript</returns>
2637
public CompileResult Compile(string source, CompileContext context)
2738
{
28-
var environment = AssemblyRegistration.Container.Resolve<IReactEnvironment>();
29-
var output = environment.TransformJsx(source);
39+
var output = _environment.TransformJsx(source);
3040
return new CompileResult(output, Enumerable.Empty<string>());
3141
}
3242
}

src/Cassette.React/MSBuildUtils.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
using System.Diagnostics;
12+
13+
namespace Cassette.React
14+
{
15+
/// <summary>
16+
/// Utility methods for interacting with Cassette in a MSBuild environment.
17+
/// </summary>
18+
public static class MSBuildUtils
19+
{
20+
/// <summary>
21+
/// Determines if the current process is MSBuild
22+
/// </summary>
23+
/// <returns><c>true</c> if we are currently in MSBuild</returns>
24+
public static bool IsInMSBuild()
25+
{
26+
try
27+
{
28+
return Process.GetCurrentProcess().ProcessName.StartsWith("MSBuild");
29+
}
30+
catch (Exception)
31+
{
32+
return false;
33+
}
34+
}
35+
}
36+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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 CassetteTinyIoCContainer = Cassette.TinyIoC.TinyIoCContainer;
11+
using ReactTinyIoCContainer = React.TinyIoC.TinyIoCContainer;
12+
using React;
13+
14+
namespace Cassette.React
15+
{
16+
/// <summary>
17+
/// Cassette IoC configuration for ReactJS.NET
18+
/// </summary>
19+
public class ReactContainerConfiguration : IConfiguration<CassetteTinyIoCContainer>
20+
{
21+
/// <summary>
22+
/// Configures the specified Cassette IoC container.
23+
/// </summary>
24+
/// <param name="container">The IoC container.</param>
25+
public void Configure(CassetteTinyIoCContainer container)
26+
{
27+
// Register ReactJS.NET's IoC container inside Cassette's.
28+
container.Register<ReactTinyIoCContainer>(global::React.AssemblyRegistration.Container);
29+
RegisterPassthru<IReactEnvironment>(container);
30+
}
31+
32+
/// <summary>
33+
/// Registers a component in Cassette's IoC container that just delegates resolution to
34+
/// ReactJS.NET's IoC container.
35+
/// </summary>
36+
/// <typeparam name="T">Type to register</typeparam>
37+
/// <param name="container">Cassette's IoC container</param>
38+
private void RegisterPassthru<T>(CassetteTinyIoCContainer container) where T : class
39+
{
40+
container.Register<T>((c, overloads) => global::React.AssemblyRegistration.Container.Resolve<T>());
41+
}
42+
}
43+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<!--
3+
The web application csproj file has been modified to execute the Bundle target.
4+
So after a build, the Cassette bundles will be saved into a cache directory.
5+
-->
6+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
7+
<UsingTask AssemblyFile="$(OutputPath)\Cassette.MSBuild.dll" TaskName="CreateBundles"/>
8+
<Target Name="Bundle">
9+
<CreateBundles />
10+
<!--
11+
CreateBundles has the following optional properties:
12+
Source: The root directory of the web application.
13+
Bin: The directory containing the web application assemblies. Default is "bin".
14+
Output: The directory to save the created bundles to. Default is "cassette-cache".
15+
AppVirtualPath: The web application's virtual path. Default is "/".
16+
IncludeOtherFiles: When true, non-bundled files such as images referenced by stylesheets are also copied to the output directory. Default is false.
17+
18+
The Web.config must also have the following section:
19+
<cassette cacheDirectory="cassette-cache" />
20+
-->
21+
</Target>
22+
</Project>

src/React.Sample.Cassette/React.Sample.Cassette.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
<Reference Include="Cassette.Aspnet">
5050
<HintPath>..\packages\Cassette.Aspnet.2.4.1\lib\net40\Cassette.Aspnet.dll</HintPath>
5151
</Reference>
52+
<Reference Include="Cassette.MSBuild">
53+
<HintPath>..\packages\Cassette.MSBuild.2.4.1\lib\net40\Cassette.MSBuild.dll</HintPath>
54+
</Reference>
5255
<Reference Include="Cassette.Views">
5356
<HintPath>..\packages\Cassette.Views.2.4.1\lib\net40\Cassette.Views.dll</HintPath>
5457
</Reference>
@@ -177,6 +180,9 @@
177180
<ItemGroup>
178181
<Content Include="Content\Sample.jsx" />
179182
</ItemGroup>
183+
<ItemGroup>
184+
<Content Include="Cassette.targets" />
185+
</ItemGroup>
180186
<PropertyGroup>
181187
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
182188
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
@@ -205,6 +211,9 @@
205211
</FlavorProperties>
206212
</VisualStudio>
207213
</ProjectExtensions>
214+
<Target Name="Bundle" AfterTargets="Build">
215+
<Exec Command="&quot;$(msbuildtoolspath)\msbuild.exe&quot; $(ProjectDirectory)cassette.targets /p:OutputPath=$(OutputPath) /t:Bundle /nr:false" />
216+
</Target>
208217
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
209218
Other similar extension points exist, see Microsoft.Common.targets.
210219
<Target Name="BeforeBuild">

0 commit comments

Comments
 (0)