Skip to content

Commit c7282e5

Browse files
authored
Add new architecture cpp-app template for init-windows (#12172)
## Description This PR adds the starting template for a purely "new architecture" RNW app, based on our current progress in implementing turbo modules and fabric. It also makes some supporting changes such as making sure `run-windows` still works and adding new non-UWP external property sheets. ### Type of Change - New feature (non-breaking change which adds functionality) ### Why This gives us the ability to start experimenting with fabric apps outside of the specialized versions in our repo. Closes #11908 Closes #12171 ### What Created a new generalized app template based on the `e2e-test-app-fabric` test app and the first minimal sample RNW fabric app here: https://github.com/chiaramooney/sample-fabric/. This template can be used to initialize a new RNW app using all new architecture features, on an existing react-native project. Once checked in, folks should be able to try this out with some variant of: ```cmd npx react-native@latest init testlocal --version 0.73.0-nightly-20230811-68c7cfe62 cd testlocal yarn add react-native-windows@canary yarn react-native init-windows --template cpp-app --overwrite --logging yarn react-native run-windows --no-autolink --logging ``` Metro should start as well as launch the packaged version of your app. ## Screenshots ![image](https://github.com/microsoft/react-native-windows/assets/10852185/9073e4f8-948b-4998-8d72-66e407b73190) ## Testing I created a new project (using my linked local RNW repo) using the following: ```cmd npx react-native@latest init testlocal --version 0.73.0-nightly-20230811-68c7cfe62 cd testlocal yarn add react-native-windows@canary && yarn link react-native-windows yarn react-native init-windows --template cpp-app --overwrite --logging yarn react-native run-windows --no-autolink --logging ``` ## Changelog Should this change be included in the release notes: no
1 parent 59bb63c commit c7282e5

39 files changed

+1241
-28
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Add new architecture `cpp-app` template for `init-windows`",
4+
"packageName": "@react-native-windows/cli",
5+
"email": "jthysell@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Add new architecture `cpp-app` template for `init-windows`",
4+
"packageName": "react-native-windows",
5+
"email": "jthysell@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

packages/@react-native-windows/cli/src/commands/config/configUtils.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,15 @@ export function isRnwDependencyProject(filePath: string): boolean {
110110
'Microsoft.ReactNative.Uwp.CSharpLib.targets',
111111
);
112112
} else if (projectLang === 'cpp') {
113-
return importProjectExists(
114-
projectContents,
115-
'Microsoft.ReactNative.Uwp.CppLib.targets',
113+
return (
114+
importProjectExists(
115+
projectContents,
116+
'Microsoft.ReactNative.Uwp.CppLib.targets',
117+
) ||
118+
importProjectExists(
119+
projectContents,
120+
'Microsoft.ReactNative.Composition.CppLib.targets',
121+
)
116122
);
117123
}
118124

@@ -193,9 +199,15 @@ function isRnwAppProject(filePath: string): boolean {
193199
'Microsoft.ReactNative.Uwp.CSharpApp.targets',
194200
);
195201
} else if (projectLang === 'cpp') {
196-
return importProjectExists(
197-
projectContents,
198-
'Microsoft.ReactNative.Uwp.CppApp.targets',
202+
return (
203+
importProjectExists(
204+
projectContents,
205+
'Microsoft.ReactNative.Uwp.CppApp.targets',
206+
) ||
207+
importProjectExists(
208+
projectContents,
209+
'Microsoft.ReactNative.Composition.CppApp.targets',
210+
)
199211
);
200212
}
201213

packages/@react-native-windows/cli/src/generator-common/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export function resolveContents(
7474
}
7575

7676
// Binary files, don't process these (avoid decoding as utf8)
77-
const binaryExtensions = ['.png', '.jar', '.keystore'];
77+
const binaryExtensions = ['.png', '.jar', '.keystore', '.ico', '.rc'];
7878

7979
type ContentChangedCallbackOption = 'identical' | 'changed' | 'new' | null;
8080

packages/@react-native-windows/cli/src/utils/deploy.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,44 @@ function getAppxManifestPath(
231231
return appxPath;
232232
}
233233

234+
function getAppxRecipePath(
235+
options: RunWindowsOptions,
236+
projectName?: string,
237+
): string {
238+
const appxManifestPath = path.dirname(
239+
getAppxManifestPath(options, projectName),
240+
);
241+
242+
const appxRecipeGlob = `*.build.appxrecipe`;
243+
244+
const globs = glob.sync(path.join(appxManifestPath, appxRecipeGlob));
245+
246+
let appxRecipePath: string;
247+
if (globs.length === 1 || !projectName) {
248+
appxRecipePath = globs[0];
249+
} else {
250+
const filteredGlobs = globs.filter(x => x.includes(projectName));
251+
appxRecipePath = filteredGlobs[0];
252+
if (filteredGlobs.length > 1) {
253+
newWarn(
254+
`More than one appxrecipe for ${projectName}: ${filteredGlobs.join(
255+
',',
256+
)}`,
257+
);
258+
newWarn(`Choosing ${appxRecipePath}`);
259+
}
260+
}
261+
262+
if (!appxRecipePath) {
263+
throw new CodedError(
264+
'DeployRecipeFailure',
265+
`Unable to find AppxRecipe from "${appxManifestPath}", using search path: "${appxRecipeGlob}" `,
266+
);
267+
}
268+
269+
return appxRecipePath;
270+
}
271+
234272
function parseAppxManifest(appxManifestPath: string): parse.Document {
235273
return parse(fs.readFileSync(appxManifestPath, 'utf8'));
236274
}
@@ -384,10 +422,7 @@ export async function deployToDesktop(
384422
} else {
385423
// Deploy from layout
386424
// If we have DeployAppRecipe.exe, use it (start in 16.8.4, earlier 16.8 versions have bugs)
387-
const appxRecipe = path.join(
388-
path.dirname(appxManifestPath),
389-
`${projectName}.build.appxrecipe`,
390-
);
425+
const appxRecipe = getAppxRecipePath(options, projectName);
391426
const ideFolder = `${buildTools.installationPath}\\Common7\\IDE`;
392427
const deployAppxRecipeExePath = `${ideFolder}\\DeployAppRecipe.exe`;
393428
if (

packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric/RNTesterApp-Fabric.vcxproj

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
6565
</ImportGroup>
6666
<ImportGroup Label="ReactNativeWindowsPropertySheets">
67-
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.props" />
67+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props" />
6868
</ImportGroup>
6969
<ItemDefinitionGroup>
7070
<ClCompile>
@@ -125,18 +125,13 @@
125125
</ItemGroup>
126126
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
127127
<ImportGroup Label="ReactNativeWindowsTargets">
128-
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets')" />
128+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets')" />
129129
</ImportGroup>
130-
<ItemGroup>
131-
<PackageReference Include="boost" Version="1.76.0.0" />
132-
<PackageReference Include="Microsoft.Toolkit.Win32.UI.XamlApplication" Version="6.1.3" />
133-
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.2-rc" />
134-
</ItemGroup>
135130
<Target Name="EnsureReactNativeWindowsTargets" BeforeTargets="PrepareForBuild">
136131
<PropertyGroup>
137132
<ErrorText>This project references targets in your node_modules\react-native-windows folder. The missing file is {0}.</ErrorText>
138133
</PropertyGroup>
139-
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.props'))" />
140-
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets'))" />
134+
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props'))" />
135+
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets'))" />
141136
</Target>
142137
</Project>

packages/playground/windows/playground-composition/Playground-Composition.vcxproj

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
6464
</ImportGroup>
6565
<ImportGroup Label="ReactNativeWindowsPropertySheets">
66-
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.props" />
66+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props" />
6767
</ImportGroup>
6868
<ItemDefinitionGroup>
6969
<ClCompile>
@@ -167,19 +167,16 @@
167167
</Target>
168168
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
169169
<ImportGroup Label="ReactNativeWindowsTargets">
170-
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets')" />
170+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets')" />
171171
</ImportGroup>
172172
<ItemGroup>
173-
<PackageReference Include="boost" Version="1.76.0.0" />
174-
<PackageReference Include="Microsoft.Toolkit.Win32.UI.XamlApplication" Version="6.1.3" />
175-
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.2-rc" />
176173
<PackageReference Include="$(V8PackageName)" Version="$(V8Version)" Condition="'$(UseV8)' == 'true'" />
177174
</ItemGroup>
178175
<Target Name="EnsureReactNativeWindowsTargets" BeforeTargets="PrepareForBuild">
179176
<PropertyGroup>
180177
<ErrorText>This project references targets in your node_modules\react-native-windows folder. The missing file is {0}.</ErrorText>
181178
</PropertyGroup>
182-
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.props'))" />
183-
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets'))" />
179+
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props'))" />
180+
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets'))" />
184181
</Target>
185182
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright (c) Microsoft Corporation. All rights reserved.
4+
Licensed under the MIT License.
5+
6+
This file will be consumed by ALL Win32 app and module projects (both inside
7+
and outside of this repo) that build on top of Microsoft.ReactNative.
8+
Do not make any changes here unless it applies to ALL such projects.
9+
-->
10+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
11+
<Import Project="$(MSBuildThisFileDirectory)Microsoft.ReactNative.Common.props" />
12+
</Project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright (c) Microsoft Corporation.
4+
Licensed under the MIT License.
5+
6+
This file will be consumed by ALL Win32 C++ app projects (both inside
7+
and outside of this repo) that build on top of Microsoft.ReactNative.
8+
Do not make any changes here unless it applies to ALL such projects.
9+
-->
10+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
11+
<!-- Keeping this at the top of the imports ensures we can use the autolinking
12+
process to set properties without having to edit the project file -->
13+
<Import Project="$(ProjectDir)\AutolinkedNativeModules.g.props"
14+
Condition="Exists('$(ProjectDir)\AutolinkedNativeModules.g.props')" />
15+
16+
<Import Project="$(MSBuildThisFileDirectory)Microsoft.ReactNative.Composition.Common.props" />
17+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Appx.props" />
18+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Autolink.props" />
19+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Codegen.props" />
20+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\NuGet.Cpp.props" />
21+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\WinUI.props" />
22+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\CppAppConsumeCSharpModule.props" />
23+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\PackageVersionDefinitions.props" />
24+
</Project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright (c) Microsoft Corporation.
4+
Licensed under the MIT License.
5+
6+
This file will be consumed by ALL Win32 C++ app projects (both inside
7+
and outside of this repo) that build on top of Microsoft.ReactNative.
8+
Do not make any changes here unless it applies to ALL such projects.
9+
-->
10+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
11+
<!-- Starting with the base of the UWP Cpp targets for now (until we need to start differentiating). -->
12+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets" />
13+
14+
<ItemGroup>
15+
<PackageReference Include="boost" Version="1.76.0.0" />
16+
<PackageReference Include="Microsoft.Toolkit.Win32.UI.XamlApplication" Version="6.1.3" />
17+
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.2-rc" />
18+
</ItemGroup>
19+
20+
</Project>

0 commit comments

Comments
 (0)