Skip to content
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

Re-use an existing browser tab with with the same URL when launching frontity dev #374

Merged
merged 16 commits into from Jun 2, 2020

Conversation

michalczaplinski
Copy link
Member

@michalczaplinski michalczaplinski commented Apr 14, 2020

What:

When running frontity dev, a new browser tab is reopened every time the command is run.

Now, frontity dev will attempt to re-use the already open browser tab and switch to it instead of opening a new tab, So, if you already have a tab with http://localhost:3000 open in chrome, we just switch to it. This stops the script from opening many tabs with the same location.

The implementation is a slightly modified version of create-react-app implementation https://github.com/facebook/create-react-app/blob/master/packages/react-dev-utils/openBrowser.js therefore I have retained the original MIT license in the file.

Additionally, I have pinned the react-helmet-async dependency to 1.0.4 because in the latest release they have broken the types in index.d.ts and it causes an error on npm install in our repository. staylor/react-helmet-async#91

Tasks:

  • Code
  • TypeScript
  • Test in macOS
  • Test in Ubuntu
  • Test in Windows

Unrelated:

  • Update starter themes
  • Update other packages
  • Community discussions
  • Documentation
  • Unit tests
  • End to end tests
  • TypeScript tests

@michalczaplinski michalczaplinski self-assigned this Apr 14, 2020
@changeset-bot
Copy link

changeset-bot bot commented Apr 14, 2020

🦋 Changeset is good to go

Latest commit: 2df3446

We got this.

This PR includes changesets to release 1 package
Name Type
@frontity/core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@michalczaplinski
Copy link
Member Author

I think this is the kind of change that is a great candidate for e2e testing, but I'm happy to hear other ideas on how you'd test it.

@michalczaplinski michalczaplinski changed the title Open browser tab Re-use an existing browser tab with with the same URL when launching frontity dev Apr 14, 2020
@luisherranz
Copy link
Member

Additionally, I have pinned the react-helmet-async dependency to 1.0.4 because in the latest release they have broken the types in index.d.ts and it causes an error on npm install in our repository. staylor/react-helmet-async#91

You should not have used a single PR for two different things because now I can't approve the react-helmet-async fix right away.

@luisherranz luisherranz mentioned this pull request Apr 14, 2020
10 tasks
@luisherranz
Copy link
Member

I think this is the kind of change that is a great candidate for e2e testing

Sure. What are your ideas?

@luisherranz
Copy link
Member

Is this ready for review or are you going to add tests first?

@michalczaplinski
Copy link
Member Author

michalczaplinski commented Apr 14, 2020

Sure. What are your ideas?

So, I don't think that you can test the actual functionality of this change (that it does not open a new tab but rather switch to the existing tab). Or, at least, it would be a bit absurd to try to test it this way...

Could we not try to run the cypress e2e tests against a frontity dev as well as a production bundle? This way, we can at least confirm that frontity dev is not broken

Right now, we're only building and running frontity serve:

start: npm run e2e:prod:${{ matrix.ci_node_index }}

which is calling:

frontity/package.json

Lines 7 to 9 in 107d354

"e2e:prod:all": "cd e2e/project/ && npx frontity build && npx frontity serve --port 3001",
"e2e:prod:module": "cd e2e/project/ && npx frontity build --target module && npx frontity serve --port 3001",
"e2e:prod:es5": "cd e2e/project/ && npx frontity build --target es5 && npx frontity serve --port 3001",

@luisherranz
Copy link
Member

Sure, good idea. Maybe we can even add a write to a file to make sure HMR is working.

Should we add a frontity dev e2e test to the testing roadmap? It doesn't feel like it belongs here, right?

@luisherranz luisherranz requested review from DAreRodz and removed request for DAreRodz April 15, 2020 07:04
@luisherranz
Copy link
Member

Have you tested this in Ubuntu and Windows?

@michalczaplinski
Copy link
Member Author

michalczaplinski commented Apr 15, 2020 via email

@luisherranz
Copy link
Member

luisherranz commented Apr 16, 2020

Do you know a cloud VM service that I could use or are you able to test it
yourself?

Maybe with https://crossbrowsertesting.com/ or https://www.browserstack.com/?

Can I just do it? :)

Sure.

Copy link
Member

@luisherranz luisherranz left a comment

Choose a reason for hiding this comment

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

To be consistent between args and ENV variables we need to change the browser arg of the dev command too: https://github.com/frontity/frontity/blob/dev/packages/core/src/scripts/dev.ts#L21

Also, to be consistent with the work of #262 you should rename BROWSER to FRONTITY_BROWSER.

case Actions.NONE:
// Special case: BROWSER="none" will prevent opening completely.
return false;
case Actions.SCRIPT:
Copy link
Member

Choose a reason for hiding this comment

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

What is this for?

Copy link
Member Author

Choose a reason for hiding this comment

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

@luisherranz I don't exactly know as this was copied 1:1 from create-react-app.

By just looking at the code, it seems that if the value of the BROWSER environment variable is a .js script, it executes this script instead of launching a browser. I'm not sure if this is a workaround for some edge case, etc. so I would just keep this code as is.

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't like to add code to the framework without understanding it so please check it out before we merge.

Also, if this covers some use cases, it needs to go to the documentation.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like this is just an advanced feature, in case you want to run a js script that eventually launches a browser in order to do some initialization, etc. There are some more details here: https://create-react-app.dev/docs/advanced-configuration/

Maybe this could be useful for automated testing with cypress? 🤔

@michalczaplinski
Copy link
Member Author

To be consistent between args and ENV variables we need to change the browser arg of the dev command too: https://github.com/frontity/frontity/blob/dev/packages/core/src/scripts/dev.ts#L21

I'm not sure what you mean, or perhaps it's a misunderstanding. That specific option (openBrowser) refers to whether a browser window should be opened or not. The BROWSER env variable holds the path to the default browser, so those are 2 different things if I understand you correctly.

Also, to be consistent with the work of #262 you should rename BROWSER to FRONTITY_BROWSER.

The BROWSER variable is a system-wide setting across different operating systems (and especially on linux) and not a Frontity-specific option, so I think we should just keep it as BROWSER.

@michalczaplinski
Copy link
Member Author

Also, should I wait until I add the frontity dev e2e test or can we merge it beforehand?

@luisherranz
Copy link
Member

luisherranz commented Apr 17, 2020

The BROWSER env variable holds the path to the default browser, so those are 2 different things if I understand you correctly.

Looking at the code I see that you can use BROWSER=none which is basically --openBrowser=false so they overlap and it should be only one or it is going to be confusing.

If we go with BROWSER instead of --openBrowser we need to remove --openBrowser and create a --browser that matches BROWSER.

The BROWSER variable is a system-wide setting across different operating systems (and especially on linux) and not a Frontity-specific option, so I think we should just keep it as BROWSER.

Ok. For consistency with the rest of our ENV variables, what about accepting both BROWSER and FRONTITY_BROWSER? Does it make sense?

@luisherranz
Copy link
Member

should I wait until I add the frontity dev e2e test

I don't think it is related so whatever you want.

@michalczaplinski
Copy link
Member Author

Looking at the code I see that you can use BROWSER=none which is basically --openBrowser=false so they overlap and it should be only one or it is going to be confusing.

If we go with BROWSER instead of --openBrowser we need to remove --openBrowser and create a --browser that matches BROWSER.

Right, I see what you mean. I had a look and the current CLI flag is actually --dont-open-browser 😄

"--dont-open-browser",

So, I think it's fine if we just keep the BROWSER env variable as is and then the matrix of options is:

  1. BROWSER=none, whatever other flags passed - we dont open the browser
  2. BROWSER=something, --dont-open-browser - also dont open browser
  3. BROWSER=something, no CLI flags - open the browser
  4. no env variables or CLI flags - open the browser

Ok. For consistency with the rest of our ENV variables, what about accepting both BROWSER and FRONTITY_BROWSER? Does it make sense?

With respect to that I don't really have a strong opinion, but one argument in favour of just using the BROWSER variable is that some users might be already familiar with it. I don't see how anybody would be getting confused even if this one variable is not consistent in naming with the rest of variables in frontity 🙂. I think accepting 2 environmental variables that serve the same purpose would be more confusing, in my opinion!

@michalczaplinski
Copy link
Member Author

michalczaplinski commented Apr 23, 2020

@luisherranz Could you please check if this works on windows when running frontity dev ? 🙏

I've signed up for browserstack but as far as I can see I only use a browser to look at websites and I cannot use a full windows environment, unfortunately. I've tested it on MacOS and works as expected. On windows it should fall back to just opening a new tab.

Let me know if there's anything else stopping this from merging 🙂

@codecov
Copy link

codecov bot commented May 29, 2020

Codecov Report

Merging #374 into dev will not change coverage.
The diff coverage is n/a.

@luisherranz
Copy link
Member

I've finally managed to run our monorepo in Windows and try this PR, but it's not working: it opens a new tab each time you run npx frontity dev.

I don't know if I'm missing something. I'm off for today but we can take a look together next week.

@luisherranz
Copy link
Member

@DAreRodz can you test it in Ubuntu?

@DAreRodz
Copy link
Member

@DAreRodz can you test it in Ubuntu?

I've just tested it and the dev command always opens a new tab. 😕

Maybe it is because the create-react-app solution only works for OSX? Each time I run npm start in a create-react-app project also opens a new tab.

@DAreRodz
Copy link
Member

DAreRodz commented May 29, 2020

Well, it is. Looking at the code, there is only one specific case when the tab can be reused, and is this one:

// If we're on OS X, the user hasn't specifically
// requested a different browser, we can try opening
// Chrome with AppleScript. This lets us reuse an
// existing tab when possible instead of creating a new one.

The rest of the covered cases are these (and use open as we currently do):

// Another special case: on OS X, check if BROWSER has been set to "open".
// In this case, instead of passing `open` to `opn` (which won't work),
// just ignore it (thus ensuring the intended behavior, i.e. opening the system browser):
// https://github.com/facebook/create-react-app/pull/1690#issuecomment-283518768
if (process.platform === "darwin" && browser === "open") {
browser = undefined;
}
// If there are arguments, they must be passed as array with the browser
if (typeof browser === "string" && args.length > 0) {
browser = [browser].concat(args);
}
// Fallback to open
// (It will always open new tab)
try {
const options = { app: browser, wait: false, url: true };
open(url, options).catch(() => {}); // Prevent `unhandledRejection` error.
return true;
} catch (err) {
return false;
}

@luisherranz
Copy link
Member

I see, thanks @DAreRodz. @michalczaplinski can you confirm that? Is this supposed to only work on OSX?

@michalczaplinski
Copy link
Member Author

I see, thanks @DAreRodz. @michalczaplinski can you confirm that? Is this supposed to only work on OSX?

That's correct! And I'm sorry -that should have been more clear from the beginning.

By "works on windows & linux" I meant that it doesn't break anything, but the actual behaviour of preserving the tab only works on MacOS.

packages/core/package.json Outdated Show resolved Hide resolved
.changeset/rare-mayflies-clap.md Outdated Show resolved Hide resolved
Copy link
Member

@luisherranz luisherranz left a comment

Choose a reason for hiding this comment

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

Thanks @michalczaplinski. I'm really sorry it took me so long to review this. Let's merge it now 🙂

@michalczaplinski michalczaplinski merged commit 099c200 into dev Jun 2, 2020
@michalczaplinski michalczaplinski deleted the open-browser-tab branch June 2, 2020 17:36
@github-actions github-actions bot mentioned this pull request Jun 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants