-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HOLD for payment 2021-09-17] [DEV] The check port script fails on it's own and does not check if the process running on the port is a metro bundler #4819
Comments
Triggered auto assignment to @Christinadobrzyn ( |
ProposalAccording to #3718, the intention behind that script is to improve the error message when attempting to run the iOS/android app alongside the desktop and web in development, but while it does that to a certain extent, it removes some of the functionality baked into any react-native project by default. To be more specific, the ability to start the bundler manually (issue 2 in the original post). Why is it important? The I have a proposal that both allows you to keep that fancy error message and brings back the default functionality. The original check port script tries to start 3 servers on the port at the same time. I think it fails for me because it tries to start one of it's servers while another one is still occupying the port. Even if we are to fix this issue, we still need to check if the port is used by metro bundler and it's not possible with this approach. I propose using a function Basically it has 3 possible returns:
So we can replace the entire start-three-servers-at-the-same-time code with this single call. It should looks like this: isPackagerRunning().then((result) => {
if (result === 'unrecognized') {
console.error(
'The port 8081 is currently in use.',
'You can run `lsof -i :8081` to see which program is using it.\n',
);
process.exit(1);
}
}); If you still want to use it for any port you can pass a port to it: // The code from original implementation
const inputPort = Number(process.argv.slice(2)[0]);
if (Number.isNaN(inputPort) || inputPort < 0 || inputPort > 65535) {
console.error('This command requires an argument that must be a number [0-65535]\n');
process.exit(1);
}
isPackagerRunning(inputPort).then((result) => {
if (result === 'unrecognized') {
console.error(
`The port ${inputPort} is currently in use.`,
`You can run \`lsof -i :${inputPort}\` to see which program is using it.\n`,
);
process.exit(1);
}
}); With this implementation you still get the same error if port is used by anything that doesn't look like metro bundler and you don't have to kill everything on port 8081 before running |
Oh, and since this is a dev-only issue that nobody has complained about since that check-port script was merged, I am willing to contribute this one without an upwork contract. It doesn't really make sense for you to pay for something that only apparently affects one person. Thanks. |
Triggered auto assignment to @tgolen ( |
That proposal sounds mostly good to me, and thank you for volunteering to fix it! The one question I have is how are you going to access that cc @HorusGoul @thienlnam Since you wrote the script initially, it might be nice to have you weigh-in on this proposal. |
I certainly forgot to add this to the code examples above, but I would require it just like anything else in node. const {isPackagerRunning} = require('@react-native-community/cli-tools'); We don't have to install anything, we already have all the needed node modules in the project. In fact, commands |
That sounds great! I'm on board with these changes. |
Ok, great. I have a few questions:
|
Let's see what the others think. |
I agree with Horus that the port doesn't need to be flexible at this point (we can always adjust it later if we need to). I'd be OK with a name change as well, and I do not have a strong opinion about what it changes to. I think all suggestions have been fine. cc @Christinadobrzyn I am giving the official 🟢 to hire @dklymenk for this job. |
Posted in Upwork! Internal post - https://www.upwork.com/ab/applicants/1431066549132935168/job-details Hired @dklymenk! |
Hey @dklymenk, I completely agree that the
Thoughts? |
@roryabraham Sorry, but I do not understand what issue does this script solve. Is the long term idea here to get the first free port after 8080 (or 8081 for native), and pass it as an argument to the server responsible for packaging for the platform of choice? I don't think we should do anything like this. Here are some bulletpoints:
So the only issue with Expensify dev experience my proposal above doesn't solve is the one where if you start web and desktop servers first, the metro bundler won't start because it still wants to use the static port 8081. If I understand the idea behind the code above correctly - use dynamics ports for everything (not just web and desktop servers) - we are accepting the idea that metro bundler won't be always running on port 8081. If that's the case, we can just set metro bundler port to 8082 in the package.json like this diff --git a/package.json b/package.json
index 8bff03dec..29fde0639 100644
--- a/package.json
+++ b/package.json
@@ -7,12 +7,12 @@
"license": "MIT",
"private": true,
"scripts": {
- "android": "npm run check-port -- 8081 && react-native run-android",
- "ios": "npm run check-port -- 8081 && react-native run-ios",
- "ipad": "npm run check-port -- 8081 && react-native run-ios --simulator=\"iPad Pro (12.9-inch) (4th generation)\"",
- "ipad-sm": "npm run check-port -- 8081 && react-native run-ios --simulator=\"iPad Pro (9.7-inch)\"",
+ "android": "react-native run-android --port 8082",
+ "ios": "npm run check-port -- 8082 && react-native run-ios --port 8082",
+ "ipad": "npm run check-port -- 8082 && react-native run-ios --port 8082 --simulator=\"iPad Pro (12.9-inch) (4th generation)\"",
+ "ipad-sm": "npm run check-port -- 8082 && react-native run-ios --port 8082 --simulator=\"iPad Pro (9.7-inch)\"",
"desktop": "node desktop/start.js",
- "start": "react-native start",
+ "start": "react-native start --port 8082", Pros:
Cons:
|
@dklymenk thanks for the detailed analysis! I guess I didn't really think about the fact that my solution would spawn a several metro servers on different ports. The reason I gravitated towards the solution I posted in the first place is because it unifies all our app startup scripts into one place. But I think you made some good points about the cons of such a solution:
So after thinking it over some more I think that your latest proposal (using port 8082 for metro) is a great solution. Looking forward to it! |
Good. So let's confirm the exact change I'm meant to implement with others. There has been a loot of talk, so here is a summary of options we have:
const {isPackagerRunning} = require('@react-native-community/cli-tools');
isPackagerRunning().then((result) => {
if (result === 'unrecognized') {
console.error(
'The port 8081 is currently in use.',
'You can run `lsof -i :8081` to see which program is using it.\n',
);
process.exit(1);
}
});
diff --git a/package.json b/package.json
index 8bff03dec..29fde0639 100644
--- a/package.json
+++ b/package.json
@@ -7,12 +7,12 @@
"license": "MIT",
"private": true,
"scripts": {
- "android": "npm run check-port -- 8081 && react-native run-android",
- "ios": "npm run check-port -- 8081 && react-native run-ios",
- "ipad": "npm run check-port -- 8081 && react-native run-ios --simulator=\"iPad Pro (12.9-inch) (4th generation)\"",
- "ipad-sm": "npm run check-port -- 8081 && react-native run-ios --simulator=\"iPad Pro (9.7-inch)\"",
+ "android": "react-native run-android --port 8082",
+ "ios": "react-native run-ios --port 8082",
+ "ipad": "react-native run-ios --port 8082 --simulator=\"iPad Pro (12.9-inch) (4th generation)\"",
+ "ipad-sm": "react-native run-ios --port 8082 --simulator=\"iPad Pro (9.7-inch)\"",
"desktop": "node desktop/start.js",
- "start": "react-native start",
+ "start": "react-native start --port 8082",
Solution 1 Is slightly inferior to 2 because starting webpack for web and desktop will reserve ports 8080 and 8081 causing metro bundler to fail to start. Solution number 2 does not have such problem. You will never run into an error with ports unless you are working on multiple projects at the same time. Solution number 3 has all the benefits of 2 but will also yield a fancy error message if metro bundler can't start because something else is running on port 8082. |
Could we confirm the |
@HorusGoul The issue is closed, but I can still reproduce it. Neither the env var So I guess this leaves us with Solution 1? |
…Running function and rename the script
The issue has seen no discussion last week, so I opened a PR with my best take on it. I have no env setup for windows testing, so it would be nice if someone was to validate the PR on windows. Thanks. |
None of us have windows environments either, so I think we are OK with just trying out best. Thanks! |
PR submitted - under review |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by @marcaaron in version: 1.0.95-2 🚀
|
Hold for payment set to [HOLD FOR PAYMENT Sept 17] |
🚀 Deployed to production by @roryabraham in version: 1.0.96-0 🚀
|
7 days since PR deployed - paid @dklymenk in Upwork (including $250 bonus for finding and fixing the bug) and closed the job. |
If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
1. Script Fails on it's own
Action Performed:
npm run android
Expected Result:
The check port script passes and continues execution
Actual Result:
The script reports that port 8081 is used. Possibly because it tries to start 3 servers on the same port at the same time.
Workaround:
Run
npx react-native run-android
manually to avoid running the check port scriptPlatform:
Where is this issue occurring?
2. Script does not check if port is used by bundler
Action Performed:
npm start
npm run android
Expected Result:
The check port scripts doesn't error out if port 8081 is already used by metro bundler
Actual Result:
The script reports that port 8081 is used and prevents further execution
Workaround:
Run
npx react-native run-android
manually to avoid running the check port scriptPlatform:
Where is this issue occurring?
Version Number:
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos: Any additional supporting documentation
Expensify/Expensify Issue URL:
View all open jobs on GitHub
The text was updated successfully, but these errors were encountered: