From 50d43767c8f68f5c79d6a8286f830112dcdb2850 Mon Sep 17 00:00:00 2001 From: "Andrew Coates (REDMOND)" Date: Wed, 6 May 2020 14:33:46 -0700 Subject: [PATCH 1/2] Ensure InitializeCore is run before app code --- packages/E2ETest/metro.config.js | 13 +++-- .../metro.config.js | 13 +++-- packages/playground/metro.config.js | 13 +++-- .../metro-react-native-platform.js | 47 ++++++++++++++++++- packages/react-native-win32/metro.config.js | 13 +++-- .../templates/metro.config.js | 14 ++++-- vnext/metro-react-native-platform.js | 38 ++++++++++++++- vnext/metro.config.js | 21 ++++++--- 8 files changed, 148 insertions(+), 24 deletions(-) diff --git a/packages/E2ETest/metro.config.js b/packages/E2ETest/metro.config.js index a5b5455186f..dd5772a7d4b 100644 --- a/packages/E2ETest/metro.config.js +++ b/packages/E2ETest/metro.config.js @@ -6,6 +6,10 @@ */ const path = require('path'); const blacklist = require('metro-config/src/defaults/blacklist'); +const { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +} = require('react-native-windows/metro-react-native-platform'); const rnwPath = path.resolve(__dirname, '../../vnext'); @@ -19,9 +23,9 @@ module.exports = { ], resolver: { - resolveRequest: require('react-native-windows/metro-react-native-platform').reactNativePlatformResolver( - { windows: 'react-native-windows' } - ), + resolveRequest: reactNativePlatformResolver({ + windows: 'react-native-windows', + }), extraNodeModules: { // Redirect metro to rnwPath instead of node_modules/react-native-windows, since metro doesn't like symlinks 'react-native-windows': rnwPath, @@ -34,6 +38,9 @@ module.exports = { ), ]), }, + serializer: { + getModulesRunBeforeMainModule, + }, transformer: { // The cli defaults this to a full path to react-native, which bypasses the reactNativePlatformResolver above // Hopefully we can fix the default in the future diff --git a/packages/microsoft-reactnative-sampleapps/metro.config.js b/packages/microsoft-reactnative-sampleapps/metro.config.js index d850032e67a..051c80f4a7f 100644 --- a/packages/microsoft-reactnative-sampleapps/metro.config.js +++ b/packages/microsoft-reactnative-sampleapps/metro.config.js @@ -6,6 +6,10 @@ */ const path = require('path'); const blacklist = require('metro-config/src/defaults/blacklist'); +const { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +} = require('react-native-windows/metro-react-native-platform'); const rnwPath = path.resolve(__dirname, '../../vnext'); @@ -19,9 +23,9 @@ module.exports = { ], resolver: { - resolveRequest: require('react-native-windows/metro-react-native-platform').reactNativePlatformResolver( - {windows: 'react-native-windows'}, - ), + resolveRequest: reactNativePlatformResolver({ + windows: 'react-native-windows', + }), extraNodeModules: { // Redirect metro to rnwPath instead of node_modules/react-native-windows, since metro doesn't like symlinks 'react-native-windows': rnwPath, @@ -36,6 +40,9 @@ module.exports = { ), ]), }, + serializer: { + getModulesRunBeforeMainModule, + }, transformer: { // The cli defaults this to a full path to react-native, which bypasses the reactNativePlatformResolver above // Hopefully we can fix the default in the future diff --git a/packages/playground/metro.config.js b/packages/playground/metro.config.js index 6a543d2b85b..9d3e6b90a00 100644 --- a/packages/playground/metro.config.js +++ b/packages/playground/metro.config.js @@ -7,6 +7,10 @@ const fs = require('fs'); const path = require('path'); const blacklist = require('metro-config/src/defaults/blacklist'); +const { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +} = require('react-native-windows/metro-react-native-platform'); const rnwPath = fs.realpathSync( path.resolve(require.resolve('react-native-windows/package.json'), '..'), @@ -22,9 +26,9 @@ module.exports = { ], resolver: { - resolveRequest: require('react-native-windows/metro-react-native-platform').reactNativePlatformResolver( - {windows: 'react-native-windows'}, - ), + resolveRequest: reactNativePlatformResolver({ + windows: 'react-native-windows', + }), extraNodeModules: { // Redirect react-native-windows to avoid symlink (metro doesn't like symlinks) 'react-native-windows': rnwPath, @@ -36,6 +40,9 @@ module.exports = { ), ]), }, + serializer: { + getModulesRunBeforeMainModule, + }, transformer: { // The cli defaults this to a full path to react-native, which bypasses the reactNativePlatformResolver above // Hopefully we can fix the default in the future diff --git a/packages/react-native-win32/metro-react-native-platform.js b/packages/react-native-win32/metro-react-native-platform.js index c908a32c52c..daf9a550e04 100644 --- a/packages/react-native-win32/metro-react-native-platform.js +++ b/packages/react-native-win32/metro-react-native-platform.js @@ -38,4 +38,49 @@ function reactNativePlatformResolver(platformImplementations) { }; } -module.exports = {reactNativePlatformResolver}; +/** + * The CLI will get a more complete implementation of this in https://github.com/react-native-community/cli/pull/1115 + * but until then, use a solution that supports having react-native-win32 and/or react-native-windows and/or react-native-macos + */ +const getModulesRunBeforeMainModule = () => { + const options = { + paths: [process.cwd()], + }; + const modules = [ + require.resolve('react-native/Libraries/Core/InitializeCore', options), + ]; + + try { + modules.push( + require.resolve( + '@office-iss/react-native-win32/Libraries/Core/InitializeCore', + options, + ), + ); + } catch {} + + try { + modules.push( + require.resolve( + 'react-native-windows/Libraries/Core/InitializeCore', + options, + ), + ); + } catch {} + + try { + modules.push( + require.resolve( + 'react-native-macos/Libraries/Core/InitializeCore', + options, + ), + ); + } catch {} + + return modules; +}; + +module.exports = { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +}; diff --git a/packages/react-native-win32/metro.config.js b/packages/react-native-win32/metro.config.js index c15ae2c5ca5..084652f0ad0 100644 --- a/packages/react-native-win32/metro.config.js +++ b/packages/react-native-win32/metro.config.js @@ -3,6 +3,10 @@ */ const fs = require('fs'); const path = require('path'); +const { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +} = require('./metro-react-native-platform'); module.exports = { // WatchFolders is only needed due to the yarn workspace layout of node_modules, we need to watch the symlinked locations separately @@ -12,9 +16,12 @@ module.exports = { ], resolver: { - resolveRequest: require('./metro-react-native-platform').reactNativePlatformResolver( - {win32: '@office-iss/react-native-win32'}, - ), + resolveRequest: reactNativePlatformResolver({ + win32: '@office-iss/react-native-win32', + }), + }, + serializer: { + getModulesRunBeforeMainModule, }, transformer: { // The cli defaults this to a full path to react-native, which bypasses the reactNativePlatformResolver above diff --git a/vnext/local-cli/generator-windows/templates/metro.config.js b/vnext/local-cli/generator-windows/templates/metro.config.js index d3d86824f7b..a1e6b552e99 100644 --- a/vnext/local-cli/generator-windows/templates/metro.config.js +++ b/vnext/local-cli/generator-windows/templates/metro.config.js @@ -7,11 +7,16 @@ const path = require('path'); const blacklist = require('metro-config/src/defaults/blacklist'); +const { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +} = require('react-native-windows/metro-react-native-platform'); + module.exports = { resolver: { - resolveRequest: require('react-native-windows/metro-react-native-platform').reactNativePlatformResolver( - {windows: 'react-native-windows'}, - ), + resolveRequest: reactNativePlatformResolver({ + windows: 'react-native-windows', + }), blacklistRE: blacklist([ // This stops "react-native run-windows" from causing the metro server to crash if its already running new RegExp( @@ -25,6 +30,9 @@ module.exports = { ), ]), }, + serializer: { + getModulesRunBeforeMainModule, + }, transformer: { // The cli defaults this to a full path to react-native, which bypasses the reactNativePlatformResolver above // Hopefully we can fix the default in the future diff --git a/vnext/metro-react-native-platform.js b/vnext/metro-react-native-platform.js index c908a32c52c..e9acdf525a7 100644 --- a/vnext/metro-react-native-platform.js +++ b/vnext/metro-react-native-platform.js @@ -38,4 +38,40 @@ function reactNativePlatformResolver(platformImplementations) { }; } -module.exports = {reactNativePlatformResolver}; +/** + * The CLI will get a more complete implementation of this in https://github.com/react-native-community/cli/pull/1115 + * but until then, use a solution that supports having react-native-windows and/or react-native-macos + */ +const getModulesRunBeforeMainModule = () => { + const options = { + paths: [process.cwd()], + }; + const modules = [ + require.resolve('react-native/Libraries/Core/InitializeCore', options), + ]; + + try { + modules.push( + require.resolve( + 'react-native-windows/Libraries/Core/InitializeCore', + options, + ), + ); + } catch {} + + try { + modules.push( + require.resolve( + 'react-native-macos/Libraries/Core/InitializeCore', + options, + ), + ); + } catch {} + + return modules; +}; + +module.exports = { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +}; diff --git a/vnext/metro.config.js b/vnext/metro.config.js index b332c81a94e..3082ecc5edc 100644 --- a/vnext/metro.config.js +++ b/vnext/metro.config.js @@ -3,7 +3,11 @@ */ const fs = require('fs'); const path = require('path'); -const blacklist = require('metro-config/src/defaults/blacklist'); + +const { + getModulesRunBeforeMainModule, + reactNativePlatformResolver, +} = require('react-native-windows/metro-react-native-platform'); const rnwPath = __dirname; @@ -15,17 +19,20 @@ module.exports = { ], resolver: { - resolveRequest: require('./metro-react-native-platform').reactNativePlatformResolver( - { - windesktop: 'react-native-windows', - windows: 'react-native-windows', - }, - ), + resolveRequest: reactNativePlatformResolver({ + windesktop: 'react-native-windows', + windows: 'react-native-windows', + }), extraNodeModules: { // Redirect react-native-windows to this folder 'react-native-windows': rnwPath, }, }, + + serializer: { + getModulesRunBeforeMainModule, + }, + transformer: { // The cli defaults this to a full path to react-native, which bypasses the reactNativePlatformResolver above // Hopefully we can fix the default in the future From 9dd7e5b08b4ac50c5717950b71391ff8689cde51 Mon Sep 17 00:00:00 2001 From: "Andrew Coates (REDMOND)" Date: Wed, 6 May 2020 14:34:01 -0700 Subject: [PATCH 2/2] Change files --- ...ss-react-native-win32-2020-05-06-14-34-01-fixfast.json | 8 ++++++++ .../react-native-windows-2020-05-06-14-34-01-fixfast.json | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 change/@office-iss-react-native-win32-2020-05-06-14-34-01-fixfast.json create mode 100644 change/react-native-windows-2020-05-06-14-34-01-fixfast.json diff --git a/change/@office-iss-react-native-win32-2020-05-06-14-34-01-fixfast.json b/change/@office-iss-react-native-win32-2020-05-06-14-34-01-fixfast.json new file mode 100644 index 00000000000..5e0b830af9f --- /dev/null +++ b/change/@office-iss-react-native-win32-2020-05-06-14-34-01-fixfast.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Ensure InitializeCore is run before app code", + "packageName": "@office-iss/react-native-win32", + "email": "acoates@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-06T21:33:58.938Z" +} diff --git a/change/react-native-windows-2020-05-06-14-34-01-fixfast.json b/change/react-native-windows-2020-05-06-14-34-01-fixfast.json new file mode 100644 index 00000000000..566bb7c5451 --- /dev/null +++ b/change/react-native-windows-2020-05-06-14-34-01-fixfast.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Ensure InitializeCore is run before app code", + "packageName": "react-native-windows", + "email": "acoates@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-06T21:34:00.993Z" +}