diff --git a/change/react-native-windows-9a3751a7-f0ff-4185-92d1-608aa823c32a.json b/change/react-native-windows-9a3751a7-f0ff-4185-92d1-608aa823c32a.json new file mode 100644 index 00000000000..e9722590fb6 --- /dev/null +++ b/change/react-native-windows-9a3751a7-f0ff-4185-92d1-608aa823c32a.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Enable Blob module in UWP", + "packageName": "react-native-windows", + "email": "julio.rocha@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/e2e-test-app/windows/RNTesterApp/RNTesterApp.csproj b/packages/e2e-test-app/windows/RNTesterApp/RNTesterApp.csproj index 233cf98f096..5ce671711ff 100644 --- a/packages/e2e-test-app/windows/RNTesterApp/RNTesterApp.csproj +++ b/packages/e2e-test-app/windows/RNTesterApp/RNTesterApp.csproj @@ -145,7 +145,7 @@ - + 6.2.9 @@ -165,4 +165,4 @@ - + \ No newline at end of file diff --git a/packages/e2e-test-app/windows/RNTesterApp/packages.lock.json b/packages/e2e-test-app/windows/RNTesterApp/packages.lock.json index 3ac0f02233b..9abc7b4fd8d 100644 --- a/packages/e2e-test-app/windows/RNTesterApp/packages.lock.json +++ b/packages/e2e-test-app/windows/RNTesterApp/packages.lock.json @@ -22,9 +22,9 @@ }, "ReactNative.Hermes.Windows": { "type": "Direct", - "requested": "[0.11.0-ms.6, )", - "resolved": "0.11.0-ms.6", - "contentHash": "7KGeDHh4QR4ua5+aSNAfuhj1sF2PBJbTHJ9m520xo1GZZRW4cxJlyNDNjW5t/sFGeHWw/Uhs7ZrWE2maL9BOEw==" + "requested": "[0.12.1, )", + "resolved": "0.12.1", + "contentHash": "0yjt0Y2pNfqw7qUiV5Q3W8hZ2HuS3HiS135c/ILLXeRXLpQMmfq1NS3oBZ1oMZy94gSfgP9QZ/862T3qUTES1A==" }, "XamlTreeDump": { "type": "Direct", @@ -32,6 +32,11 @@ "resolved": "1.0.9", "contentHash": "rvh/RZghhSG28PDL1dw56nTZRN0/ViV2TIja/ykU9FHn0gtM8pwtgD8Ebo1nobu0QnSjn8Cg6Ncu39VV19rkrw==" }, + "boost": { + "type": "Transitive", + "resolved": "1.76.0", + "contentHash": "p+w3YvNdXL8Cu9Fzrmexssu0tZbWxuf6ywsQqHjDlKFE5ojXHof1HIyMC3zDLfLnh80dIeFcEUAuR2Asg/XHRA==" + }, "Microsoft.Net.Native.Compiler": { "type": "Transitive", "resolved": "2.2.7-rel-27913-00", @@ -56,7 +61,17 @@ "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "2.1.0", - "contentHash": "ok+RPAtESz/9MUXeIEz6Lv5XAGQsaNmEYXMsgVALj4D7kqC8gveKWXWXbufLySR2fWrwZf8smyN5RmHu0e4BHA==" + "contentHash": "GmkKfoyerqmsHMn7OZj0AKpcBabD+GaafqphvX2Mw406IwiJRy1pKcKqdCfKJfYmkRyJ6+e+RaUylgdJoDa1jQ==" + }, + "Microsoft.Windows.CppWinRT": { + "type": "Transitive", + "resolved": "2.0.211028.7", + "contentHash": "JBGI0c3WLoU6aYJRy9Qo0MLDQfObEp+d4nrhR95iyzf7+HOgjRunHDp/6eGFREd7xq3OI1mll9ecJrMfzBvlyg==" + }, + "Microsoft.Windows.SDK.BuildTools": { + "type": "Transitive", + "resolved": "10.0.22000.194", + "contentHash": "4L0P3zqut466SIqT3VBeLTNUQTxCBDOrTRymRuROCRJKazcK7ibLz9yAO1nKWRt50ttCj39oAa2Iuz9ZTDmLlg==" }, "NETStandard.Library": { "type": "Transitive", @@ -134,11 +149,39 @@ "contentHash": "qF6RRZKaflI+LR1YODNyWYjq5YoX8IJ2wx5y8O+AW2xO+1t/Q6Mm+jQ38zJbWnmXbrcOqUYofn7Y3/KC6lTLBQ==" }, "automationchannel": { + "type": "Project", + "dependencies": { + "Microsoft.ReactNative": "1.0.0", + "Microsoft.UI.Xaml": "2.7.0", + "Microsoft.Windows.CppWinRT": "2.0.211028.7" + } + }, + "common": { "type": "Project" }, - "microsoft.reactnative": { + "fmt": { "type": "Project" }, + "folly": { + "type": "Project", + "dependencies": { + "boost": "1.76.0", + "fmt": "1.0.0" + } + }, + "microsoft.reactnative": { + "type": "Project", + "dependencies": { + "Common": "1.0.0", + "Folly": "1.0.0", + "Microsoft.UI.Xaml": "2.7.0", + "Microsoft.Windows.CppWinRT": "2.0.211028.7", + "Microsoft.Windows.SDK.BuildTools": "10.0.22000.194", + "ReactCommon": "1.0.0", + "ReactNative.Hermes.Windows": "0.12.1", + "boost": "1.76.0" + } + }, "microsoft.reactnative.managed": { "type": "Project", "dependencies": { @@ -146,16 +189,25 @@ "Microsoft.ReactNative": "1.0.0" } }, + "reactcommon": { + "type": "Project", + "dependencies": { + "Folly": "1.0.0", + "boost": "1.76.0" + } + }, "reactnativepicker": { "type": "Project", "dependencies": { - "Microsoft.ReactNative": "1.0.0" + "Microsoft.ReactNative": "1.0.0", + "Microsoft.UI.Xaml": "2.7.0" } }, "reactnativexaml": { "type": "Project", "dependencies": { - "Microsoft.ReactNative": "1.0.0" + "Microsoft.ReactNative": "1.0.0", + "Microsoft.UI.Xaml": "2.7.0" } } }, diff --git a/vnext/Microsoft.ReactNative/Base/CoreNativeModules.cpp b/vnext/Microsoft.ReactNative/Base/CoreNativeModules.cpp index a2a2c9d3b36..9522dc4b59a 100644 --- a/vnext/Microsoft.ReactNative/Base/CoreNativeModules.cpp +++ b/vnext/Microsoft.ReactNative/Base/CoreNativeModules.cpp @@ -19,8 +19,12 @@ namespace Microsoft::ReactNative { +using winrt::Microsoft::ReactNative::ReactPropertyBag; + namespace { +using winrt::Microsoft::ReactNative::ReactPropertyId; + bool HasPackageIdentity() noexcept { static const bool hasPackageIdentity = []() noexcept { auto packageStatics = winrt::get_activation_factory( @@ -35,6 +39,13 @@ bool HasPackageIdentity() noexcept { return hasPackageIdentity; } +ReactPropertyId HttpUseMonolithicModuleProperty() noexcept { + static ReactPropertyId propId{ + L"ReactNative.Http" + L"UseMonolithicModule"}; + return propId; +} + } // namespace std::vector GetCoreModules( @@ -50,11 +61,25 @@ std::vector GetCoreModules( [props = context->Properties()]() { return Microsoft::React::CreateHttpModule(props); }, jsMessageQueue); + if (!ReactPropertyBag(context->Properties()).Get(HttpUseMonolithicModuleProperty())) { + modules.emplace_back( + Microsoft::React::GetBlobModuleName(), + [props = context->Properties()]() { return Microsoft::React::CreateBlobModule(props); }, + batchingUIMessageQueue); + + modules.emplace_back( + Microsoft::React::GetFileReaderModuleName(), + [props = context->Properties()]() { return Microsoft::React::CreateFileReaderModule(props); }, + batchingUIMessageQueue); + } + modules.emplace_back( "Timing", [batchingUIMessageQueue]() { return facebook::react::CreateTimingModule(batchingUIMessageQueue); }, batchingUIMessageQueue); + // Note: `context` is moved to remove the reference from the current scope. + // This should either be the last usage of `context`, or the std::move call should happen later in this method. modules.emplace_back( NativeAnimatedModule::name, [context = std::move(context)]() mutable { return std::make_unique(std::move(context)); }, diff --git a/vnext/Shared/OInstance.cpp b/vnext/Shared/OInstance.cpp index 329e79e9693..033639f7b30 100644 --- a/vnext/Shared/OInstance.cpp +++ b/vnext/Shared/OInstance.cpp @@ -545,6 +545,7 @@ std::vector> InstanceImpl::GetDefaultNativeModules std::vector> modules; auto transitionalProps{ReactPropertyBagHelper::CreatePropertyBag()}; +#if (defined(_MSC_VER) && !defined(WINRT)) modules.push_back(std::make_unique( m_innerInstance, Microsoft::React::GetHttpModuleName(), @@ -552,6 +553,7 @@ std::vector> InstanceImpl::GetDefaultNativeModules return Microsoft::React::CreateHttpModule(transitionalProps); }, nativeQueue)); +#endif modules.push_back(std::make_unique( m_innerInstance, @@ -619,8 +621,13 @@ std::vector> InstanceImpl::GetDefaultNativeModules []() { return std::make_unique(); }, nativeQueue)); - // #10036 - Blob module not supported in UWP. Need to define property bag lifetime and onwership. - if (Microsoft::React::GetRuntimeOptionBool("Blob.EnableModule")) { + // These modules are instantiated separately in MSRN (Universal Windows). + // When there are module name colisions, the last one registered is used. + // If this code is enabled, we will have unused module instances. + // Also, MSRN has a different property bag mechanism incompatible with this method's transitionalProps variable. +#if (defined(_MSC_VER) && !defined(WINRT)) + if (Microsoft::React::GetRuntimeOptionBool("Blob.EnableModule") && + !Microsoft::React::GetRuntimeOptionBool("Http.UseMonolithicModule")) { modules.push_back(std::make_unique( m_innerInstance, Microsoft::React::GetBlobModuleName(), @@ -633,6 +640,7 @@ std::vector> InstanceImpl::GetDefaultNativeModules [transitionalProps]() { return Microsoft::React::CreateFileReaderModule(transitionalProps); }, nativeQueue)); } +#endif return modules; }