Skip to content

Commit

Permalink
Cleanup ReactNativeAppBuilder and ReactNativeWin32App (#13983)
Browse files Browse the repository at this point in the history
## Description

This PR simplifies and scopes down the API for `ReactNativeAppBuilder` and `ReactNativeWin32App`.

### Type of Change
- Bug fix (non-breaking change which fixes an issue)

### Why
`ReactNativeAppBuilder`'s API surface made it too easy to call incorrectly and not realize it.

Resolves #13946

### What

There are a variety of changes to the API surface:
* `ReactInstanceSettingsBuilder` deleted: not only are there are simply too many APIs that would need to be exposed to be useful, the very act of creating and replacing the app's `ReactNativeHost`'s `ReactInstanceSettings` with a new one is what caused the bug in #13946 in the first place
* `ReactNativeAppBuilder` now only exposes APIs to specify the intial, non-ReactNative, WinAppSDK types, (i.e. `DispatcherQueueController`, `Compositor`, and `AppWindow`), objects the app developer may already have created for their existing app, and otherwise is only responsible for building a `ReactNativeWin32App` with those types properly pre-made
* `ReactNativeWin32App::Start()` is now more responsible for the stitching together all of the relevant types to make a working Win32 fabric app
* All WinRT APIs without an immediate use-case have been commented out until we are sure they are necessary and that it is safe to expose them
* The template has been updated to follow the pattern of:
    * Use `ReactNativeAppBuilder` to get a `ReactNativeWin32` app with the base WinAppSDK types ready
    * Get and modify the types as necessary from the created app object (like the `ReactInstanceSettings` and the `AppWindow`)
    * Call `app.Start()`

## Screenshots
N/A

## Testing
Verified new apps and example apps in libraryes build and run properly.

## Changelog
Should this change be included in the release notes: _yes_

Cleanup ReactNativeAppBuilder and ReactNativeWin32App
  • Loading branch information
jonthysell authored Oct 21, 2024
1 parent 1346dc5 commit e1b07c7
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 370 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Cleanup ReactNativeAppBuilder and ReactNativeWin32App",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "NativeModules.h"

// A PackageProvider containing any turbo modules you define within this app project
struct CompReactPackageProvider
: winrt::implements<CompReactPackageProvider, winrt::Microsoft::ReactNative::IReactPackageProvider> {
public: // IReactPackageProvider
Expand All @@ -16,65 +17,66 @@ struct CompReactPackageProvider
}
};

// Global Variables:
constexpr PCWSTR windowTitle = L"sample_app_fabric";
constexpr PCWSTR mainComponentName = L"sample_app_fabric";

// The entry point of the Win32 application
_Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR /* commandLine */, int showCmd) {
// Initialize WinRT.
// Initialize WinRT
winrt::init_apartment(winrt::apartment_type::single_threaded);

// Enable per monitor DPI scaling
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

// Create a top-level window.
auto window = winrt::Microsoft::UI::Windowing::AppWindow::Create();
window.Title(windowTitle);
window.Resize({1000, 1000});
window.Show();

// Find the path hosting the app exe file
WCHAR appDirectory[MAX_PATH];
GetModuleFileNameW(NULL, appDirectory, MAX_PATH);
PathCchRemoveFileSpec(appDirectory, MAX_PATH);

// DebugBundlePath is used when loading from a bundle server such as metro. If this parameter
// is not provided fallback to a combination of JavaScriptBundleFile and BundleRootPath
auto reactInstanceSettingsBuilder {
winrt::Microsoft::ReactNative::ReactInstanceSettingsBuilder()
.DebugBundlePath(L"index")
.JavaScriptBundleFile(L"index.windows")
.BundleRootPath(std::wstring(L"file://").append(appDirectory).append(L"\\Bundle\\").c_str())
// Create a ReactNativeWin32App with the ReactNativeAppBuilder
auto reactNativeWin32App{winrt::Microsoft::ReactNative::ReactNativeAppBuilder().Build()};

// Configure the initial InstanceSettings for the app's ReactNativeHost
auto settings{reactNativeWin32App.ReactNativeHost().InstanceSettings()};
// Register any autolinked native modules
RegisterAutolinkedNativeModulePackages(settings.PackageProviders());
// Register any native modules defined within this app project
settings.PackageProviders().Append(winrt::make<CompReactPackageProvider>());

#if BUNDLE
.UseFastRefresh(false)
// Load the JS bundle from a file (not Metro):
// Set the path (on disk) where the .bundle file is located
settings.BundleRootPath(std::wstring(L"file://").append(appDirectory).append(L"\\Bundle\\").c_str());
// Set the name of the bundle file (without the .bundle extension)
settings.JavaScriptBundleFile(L"index.windows");
// Disable hot reload
settings.UseFastRefresh(false);
#else
.UseFastRefresh(true)
// Load the JS bundle from Metro
settings.JavaScriptBundleFile(L"index");
// Enable hot reload
settings.UseFastRefresh(true);
#endif
#if _DEBUG
.UseDirectDebugger(true)
.UseDeveloperSupport(true)
// For Debug builds
// Enable Direct Debugging of JS
settings.UseDirectDebugger(true);
// Enable the Developer Menu
settings.UseDeveloperSupport(true);
#else
.UseDirectDebugger(false)
.UseDeveloperSupport(false)
// For Release builds:
// Disable Direct Debugging of JS
settings.UseDirectDebugger(false);
// Disable the Developer Menu
settings.UseDeveloperSupport(false);
#endif
};

auto packageProviders{winrt::single_threaded_vector<winrt::Microsoft::ReactNative::IReactPackageProvider>()};

RegisterAutolinkedNativeModulePackages(packageProviders);
packageProviders.Append(winrt::make<CompReactPackageProvider>());

winrt::Microsoft::ReactNative::ReactViewOptions viewOptions;
viewOptions.ComponentName(mainComponentName);

// Initialize and Manage the ReactNativeHost
auto reactNativeAppBuilder{winrt::Microsoft::ReactNative::ReactNativeAppBuilder()
.AddPackageProviders(packageProviders)
.SetReactInstanceSettings(reactInstanceSettingsBuilder.ReactInstanceSettings())
.SetAppWindow(window)
.SetReactViewOptions(viewOptions)};
// Get the AppWindow so we can configure its initial title and size
auto appWindow{reactNativeWin32App.AppWindow()};
appWindow.Title(L"sample_app_fabric");
appWindow.Resize({1000, 1000});

// Start the react-native instance by creating a javascript runtime and load the bundle.
auto reactNativeWin32App{reactNativeAppBuilder.Build()};
// Get the ReactViewOptions so we can set the initial RN component to load
auto viewOptions{reactNativeWin32App.ReactViewOptions()};
viewOptions.ComponentName(L"sample_app_fabric");

// Start the app
reactNativeWin32App.Start();
}
59 changes: 0 additions & 59 deletions vnext/Microsoft.ReactNative/ReactInstanceSettingsBuilder.cpp

This file was deleted.

23 changes: 0 additions & 23 deletions vnext/Microsoft.ReactNative/ReactInstanceSettingsBuilder.h

This file was deleted.

Loading

0 comments on commit e1b07c7

Please sign in to comment.