Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ado/windows-vs-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ jobs:
displayName: Check the metro bundle server
inputs:
targetType: 'inline'
script: Invoke-WebRequest -Uri "http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=windesktop&dev=true"
script: Invoke-WebRequest -Uri "http://localhost:8081/react-native-installation/IntegrationTests/IntegrationTestsApp.bundle?platform=windesktop&dev=true"
condition: failed()

- template: templates/stop-packagers.yml
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "refactor react-native-windows installation for better metro support",
"packageName": "@office-iss/react-native-win32",
"email": "kmelmon@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-04-11T21:57:04.043Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "refactor react-native-windows install to better support metro",
"packageName": "react-native-windows",
"email": "kmelmon@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-04-10T18:55:54.788Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "refactor react-native-windows installation for better metro support",
"packageName": "react-native-windows",
"email": "kmelmon@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-04-11T21:57:30.042Z"
}
7 changes: 4 additions & 3 deletions packages/E2ETest/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const rnPath = fs.realpathSync(
);
const rnwPath = path.resolve(__dirname, '../../vnext');

const rnInstallPath = fs.realpathSync(path.resolve(rnwPath, './react-native-installation'));

module.exports = {
// WatchFolders is only needed due to the yarn workspace layout of node_modules, we need to watch the symlinked locations separately
watchFolders: [
Expand All @@ -24,9 +26,8 @@ module.exports = {

resolver: {
extraNodeModules: {
// Redirect metro to rnwPath instead of node_modules/react-native-windows, since metro doesn't like symlinks
'react-native': rnwPath,
'react-native-windows': rnwPath,
// Redirect react-native to the installation path, up and over in vnext/react-native-installation
'react-native': rnInstallPath,
},
// Include the macos platform in addition to the defaults because the fork includes macos, but doesn't declare it
platforms: ['ios', 'android', 'windesktop', 'windows', 'web', 'macos'],
Expand Down
3 changes: 3 additions & 0 deletions packages/E2ETest/postinstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ link(
'rnpm-plugin-windows',
path.resolve(require.resolve('rnpm-plugin-windows/package.json'), '..'),
);



Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

3 changes: 2 additions & 1 deletion packages/E2ETest/react-native.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const path = require('path');
module.exports = {
reactNativePath: '../../vnext',
reactNativePath: path.resolve(__dirname, '../../vnext/react-native-installation'),
};
8 changes: 4 additions & 4 deletions packages/microsoft-reactnative-sampleapps/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const rnPath = fs.realpathSync(
);
const rnwPath = path.resolve(__dirname, '../../vnext');

const rnInstallPath = fs.realpathSync(path.resolve(rnwPath, './react-native-installation'));

module.exports = {
// WatchFolders is only needed due to the yarn workspace layout of node_modules, we need to watch the symlinked locations separately
watchFolders: [
Expand All @@ -24,14 +26,12 @@ module.exports = {

resolver: {
extraNodeModules: {
// Redirect metro to rnwPath instead of node_modules/react-native-windows, since metro doesn't like symlinks
'react-native': rnwPath,
'react-native-windows': rnwPath,
// Redirect react-native to the installation path, up and over in vnext/react-native-installation
'react-native': rnInstallPath,
},
// Include the macos platform in addition to the defaults because the fork includes macos, but doesn't declare it
platforms: ['ios', 'android', 'windesktop', 'windows', 'web', 'macos'],
// Since there are multiple copies of react-native, we need to ensure that metro only sees one of them
// This should go away after RN 0.60 when haste is removed
blacklistRE: blacklist([
new RegExp(
'.*microsoft-reactnative-sampleapps/msbuild.*'.replace(/[/\\]/g, '\\/'),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const path = require('path');
module.exports = {
reactNativePath: '../../vnext',
reactNativePath: path.resolve(__dirname, '../../vnext/react-native-installation'),
};
8 changes: 4 additions & 4 deletions packages/playground/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const rnwPath = fs.realpathSync(
path.resolve(require.resolve('react-native-windows/package.json'), '..'),
);

const rnInstallPath = fs.realpathSync(path.resolve(rnwPath, './react-native-installation'));

module.exports = {
// WatchFolders is only needed due to the yarn workspace layout of node_modules, we need to watch the symlinked locations separately
watchFolders: [
Expand All @@ -26,14 +28,12 @@ module.exports = {

resolver: {
extraNodeModules: {
// Redirect react-native to react-native-windows
'react-native': rnwPath,
'react-native-windows': rnwPath,
// Redirect react-native to the installation path, up and over in vnext/react-native-installation
'react-native': rnInstallPath,
},
// Include the macos platform in addition to the defaults because the fork includes macos, but doesn't declare it
platforms: ['ios', 'android', 'windesktop', 'windows', 'web', 'macos'],
// Since there are multiple copies of react-native, we need to ensure that metro only sees one of them
// This should go in RN 0.61 when haste is removed
blacklistRE: blacklist([
new RegExp(
`${(path.resolve(rnPath) + path.sep).replace(/[/\\]/g, '/')}.*`,
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/react-native.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ const fs = require('fs');
const path = require('path');
module.exports = {
reactNativePath: fs.realpathSync(
path.resolve(require.resolve('react-native-windows/package.json'), '..'),
path.resolve(require.resolve('react-native-windows/package.json'), '../react-native-installation'),
),
};
3 changes: 2 additions & 1 deletion packages/react-native-win32/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
/RNTester
/RNTester.*
/temp
/WorkingHeaders
/WorkingHeaders
/react-native-installation
91 changes: 91 additions & 0 deletions packages/react-native-win32/Scripts/copyRNWin32Libraries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* @format
*/
// @ts-check
const path = require('path');
const fs = require('fs');
const glob = require('glob');
const rimraf = require('rimraf');

function retryOnError(errorCode, func) {
const startTime = Date.now();

while (true) {
try {
func();
return true;
} catch (ex) {
if (ex.code !== errorCode) {
throw ex;
}
}

if (Date.now() - startTime > 5000) {
return false;
}
}
}

function copyDirectories(srcPath, targetPath, dirSpecs) {
dirSpecs.forEach(dirSpec => {
if (dirSpec.mergeFiles !== true) {
// rimraf issue 72: We will see ENOTEMPTY if Windows is still holding a
// lock to a file in our directory. E.g. if we get unlucky with timing
// and antivirus decides to run. Keep on spinning until we're able to
// delete the directory.
let deleted = retryOnError('ENOTEMPTY', () => {
if (dirSpec.rmFilter === undefined) {
rimraf.sync(path.resolve(targetPath, dirSpec.dest));
} else {
rimraf.sync(
path.resolve(targetPath, dirSpec.dest + path.sep + dirSpec.filter),
);
}
});

if (!deleted) {
throw new Error(
'Timed out trying to delete directory. Ensure no locks are being held to project files and try again.',
);
}
}

const curSrcPath = path.resolve(srcPath, dirSpec.src);
const curTargetPath = path.resolve(targetPath, dirSpec.dest);

glob.sync('**/*.{js,png,gif,h}', {cwd: curSrcPath}).forEach(file => {
const dir = path.dirname(file);
const targetDir = path.resolve(curTargetPath, dir);
const targetFile = path.resolve(curTargetPath, file);

fs.mkdirSync(targetDir, {recursive: true});
fs.writeFileSync(
targetFile,
fs.readFileSync(path.join(curSrcPath, file)),
);
});
});
}

function copyFile(srcPath, targetPath, filename) {
fs.writeFileSync(
path.resolve(targetPath, filename),
fs.readFileSync(path.resolve(srcPath, filename)),
);
}

exports.copyRNWin32Libraries = baseDir => {

const rnInstallationPath = path.resolve(baseDir, './react-native-installation');

copyDirectories(baseDir, rnInstallationPath, [
{
src: 'RNTester',
dest: 'RNTester',
mergeFiles: true,
},
]);

copyFile(baseDir, rnInstallationPath, 'RNTester.js');
copyFile(baseDir, rnInstallationPath, 'RNTester.js.map');
};
11 changes: 9 additions & 2 deletions packages/react-native-win32/just-task.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ task('copyPngFiles', () => {
task('initRNLibraries', () => {
require('../../vnext/scripts/copyRNLibraries').copyRNLibraries(__dirname);
});

task('installRNW', () => {
require('../../vnext/Scripts/installRNW').installRNW(__dirname, path.resolve(__dirname, './react-native-installation'));
});
task('copyRNWin32Libraries', () => {
require('./Scripts/copyRNWin32Libraries').copyRNWin32Libraries(__dirname);
});
task('flow-check', () => {
require('child_process').execSync('npx flow check', { stdio: 'inherit' });
});
Expand Down Expand Up @@ -94,10 +99,12 @@ task(
'build',
series(
condition('clean', () => argv().clean),
'initRNLibraries',
'copyFlowFiles',
'copyPngFiles',
'ts',
'installRNW',
'initRNLibraries',
'copyRNWin32Libraries',
condition('apiExtractorVerify', () => argv().ci),
),
);
Expand Down
8 changes: 4 additions & 4 deletions packages/react-native-win32/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const rnPath = fs.realpathSync(
path.resolve(require.resolve('react-native/package.json'), '..'),
),
);
const rnw32Path = __dirname;
const rnInstallPath = path.resolve(__dirname, './react-native-installation');

module.exports = {
// WatchFolders is only needed due to the yarn workspace layout of node_modules, we need to watch the symlinked locations separately
Expand All @@ -21,9 +21,9 @@ module.exports = {

resolver: {
extraNodeModules: {
// Redirect react-native and react-native-windows to this folder
'react-native': rnw32Path,
'react-native-win32': rnw32Path,
// Redirect react-native to the installation path
'react-native-windows': rnInstallPath,
'react-native': rnInstallPath,
},
// Include the macos platform in addition to the defaults because the fork includes macos, but doesn't declare it
platforms: [
Expand Down
6 changes: 3 additions & 3 deletions packages/react-native-win32/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"version": "0.0.0-master.3",
"description": "Implementation of react native on top of Office's Win32 platform.",
"license": "MIT",
"main": "./Libraries/react-native/react-native-implementation.win32.js",
"typings": "./Libraries/react-native/typings-main.d.ts",
"main": "Libraries/react-native/react-native-implementation.win32.js",
"typings": "Libraries/react-native/typings-main.d.ts",
"scripts": {
"build": "just-scripts build",
"bundle": "just-scripts prepareBundle && react-native bundle --platform win32 --entry-file RNTester.js --bundle-output dist/win32/dev/RNTester.bundle --assets-dest dist/win32/dev --sourcemap-output ./dist/win32/dev/sourcemap.js",
"bundle": "just-scripts prepareBundle && react-native bundle --platform win32 --entry-file react-native-installation/RNTester.js --bundle-output dist/win32/dev/RNTester.bundle --assets-dest dist/win32/dev --sourcemap-output ./dist/win32/dev/sourcemap.js",
"change": "beachball change",
"clean": "just-scripts clean",
"flow-check": "flow check",
Expand Down
3 changes: 2 additions & 1 deletion packages/react-native-win32/react-native.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-check

const path = require('path');
module.exports = {
platforms: {
win32: {
Expand All @@ -11,5 +12,5 @@ module.exports = {

// *****
// This is only used when building bundles within react-native-win32.
reactNativePath: '.',
reactNativePath: path.resolve(__dirname, './react-native-installation'),
};
3 changes: 2 additions & 1 deletion vnext/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
/RNTester
/index.*
/RNTester.*
/jest
/jest
/react-native-installation
1 change: 1 addition & 0 deletions vnext/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ node_modules
/RNTester
/RNTester.*
/index.*
/react-native-installation

# Visual Studio
.vs/
Expand Down
1 change: 1 addition & 0 deletions vnext/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ReactWindows-Universal.sln
ReactWindows-Desktop.sln
RNTester.*
RNTester/
react-native-installation
src/
target
temp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ TEST_CLASS (WebSocketIntegrationTest)
// string url = "ws://localhost:5555/";
auto ws = IWebSocketResource::Make(url);
string json =
"{\"inject\":{},\"id\":1,\"method\":\"executeApplicationScript\",\"url\":\"http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true\"}";
"{\"inject\":{},\"id\":1,\"method\":\"executeApplicationScript\",\"url\":\"http://localhost:8081/react-native-installation/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true\"}";
// string json = "{}";
std::mutex mutex;
condition_variable condition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ TEST_CLASS (WebSocketJSExecutorIntegrationTest) {
bool connected = jse->ConnectAsync("ws://localhost:8081/debugger-proxy?role=client", move(errorCallback)).get();
// Point to an existing script accessible via the repository's packaging
// service.
auto bigString = unique_ptr<JSBigString>(
new JSBigStdString("http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true"));
auto bigString = unique_ptr<JSBigString>(new JSBigStdString(
"http://localhost:8081/react-native-installation/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true"));
jse->loadApplicationScript(std::move(bigString), "");

jsQueue->quitSynchronous();
Expand Down
3 changes: 2 additions & 1 deletion vnext/IntegrationTests/TestRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ TestResult TestRunner::RunTest(string &&bundlePath, string &&appName, NativeLogg

// React instance scope
{
string realBundlePath = "react-native-installation/" + bundlePath;
shared_ptr<ITestInstance> instance =
GetInstance(std::move(bundlePath), std::move(modules), std::move(devSettings));
GetInstance(std::move(realBundlePath), std::move(modules), std::move(devSettings));

InitializeLogging([&result, &functionCalled](RCTLogLevel logLevel, const char *message) {
if (TestStatus::Pending != result.Status)
Expand Down
2 changes: 1 addition & 1 deletion vnext/Scripts/IntegrationTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ if (! $NoServers) {
Start-Sleep -Seconds $Delay

# Preload the RNTesterApp integration bundle for better performance in integration tests.
Invoke-WebRequest -Uri "http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=windesktop&dev=true" | Out-Null
Invoke-WebRequest -Uri "http://localhost:8081/react-native-installation/IntegrationTests/IntegrationTestsApp.bundle?platform=windesktop&dev=true" | Out-Null
}
}

Expand Down
2 changes: 1 addition & 1 deletion vnext/Scripts/Tfs/Start-TestServers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ if ($Preload) {
Start-Sleep -Seconds $SleepSeconds

# Preload the RNTesterApp integration bundle for better performance in integration tests.
Invoke-WebRequest -Uri "http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=windesktop&dev=true" | Out-Null
Invoke-WebRequest -Uri "http://localhost:8081/react-native-installation/IntegrationTests/IntegrationTestsApp.bundle?platform=windesktop&dev=true" | Out-Null

Write-Host 'Done preloading bundles.'
}
Expand Down
Loading