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 current tab instead of open a new one #1400

Open
1 of 2 tasks
elrumordelaluz opened this issue May 4, 2018 · 24 comments
Open
1 of 2 tasks

Re-use current tab instead of open a new one #1400

elrumordelaluz opened this issue May 4, 2018 · 24 comments

Comments

@elrumordelaluz
Copy link
Contributor

  • Operating System: OSX
  • Node Version: 8.11.0
  • NPM Version: 6.0.0
  • webpack Version: 4.7.0
  • webpack-dev-server Version: 3.1.4
  • This is a bug
  • This is a modification request

Code

  // webpack.config.js
  // additional code, remove if not needed.

Expected Behavior

Try to refresh the current browser window

Actual Behavior

Open always a new tab

For Bugs; How can we reproduce the behavior?

For Features; What is the motivation and/or use-case for the feature?

Inspired on create-react-app solution.

Since I usually use Google Chrome, I expect to stay in the same (current) browser tab
when re-launch webpack-dev-server, instead of use a new one and close those more.

Just curious if the Webpack people/ecosystem are interested in having this behaviour (will PR in case), since is very specific to Chrome browser in OSX platform.

Furthermore, the solution requires to have an extra file .applescript in the package.

Thoughts?

related #1185

@alexander-akait

This comment has been minimized.

@elrumordelaluz

This comment has been minimized.

@alexander-akait

This comment has been minimized.

@elrumordelaluz

This comment has been minimized.

@alexander-akait
Copy link
Member

@elrumordelaluz yes, here issue webpack/webpack.js.org#2069

@flekschas
Copy link

Just in case somebody else stumbles upon this ticket and wonders "should I use webpack-serve"? webpack-serve is now deprecated!

DEPRECATED. Please use webpack-dev-server (he is in support and update mode again). Feel free to create a issue if some features are not implemented in webpack-dev-server.

@alexander-akait
Copy link
Member

feel free to send a PR

@flekschas
Copy link

Just as a reference, @elrumordelaluz submitted a PR to webpack-serve regarding this matter: webpack-contrib/webpack-serve#117

Since it's much more involved than I thought it would be I am not sure it's simply to copy it over to webpack-dev-server. :)

@alexander-akait
Copy link
Member

@flekschas feel free to send a PR

@alexander-akait
Copy link
Member

Oh we don't have event/hooks right now, we need implement their

@speaud
Copy link

speaud commented Feb 26, 2020

Would it be possible for the devServer.open property to accept a function? Maybe then the developer could write a function to check if a active session already exists. Possibly using the tabs.query() method.

@ghost
Copy link

ghost commented Mar 30, 2020

vue-cli does this pretty well!
Also webpack-serve seems like made something for this. webpack-contrib/webpack-serve#117

@alexander-akait
Copy link
Member

@atilkan PR welcome if you have idea how to implement it

@Akiyamka
Copy link

I have an idea for a more cross platform solution - we could add a shortcut (R - reload) for restart webpack from terminal. Similar to how it works in jest - by press R webpack restarting and refresh the already opened page.
Because we know that webpack already run open and openPage options will not triggered again.

@ckken
Copy link

ckken commented Jun 29, 2020

mark

@kaspar-p
Copy link

kaspar-p commented Jul 14, 2020

There is a holdover solution for people waiting on this feature to be implemented into webpack-dev-server. The way create-react-app does it is with a react-dev-utils script called openBrowser. Importing this function into a webpack after function with the parameter of the host and port, works perfectly.

// webpack.config.js or webpack.config.babel.js
import openBrowser from "react-dev-utils/openBrowser";
...
devServer: { ..., after: () => { openBrowser("http://localhost:8080"); }, ... }

With one other caveat, the .applescript file needs to be copied into the root of your project. Information about that script and where to find these files here: https://stackoverflow.com/questions/48913566/how-does-create-react-app-re-use-an-existing-browser-tab-after-running-npm-run/48915952

@Akiyamka
Copy link

@Kaspar78 it's work only for mac platform

@ckken
Copy link

ckken commented Jul 17, 2020

There is a holdover solution for people waiting on this feature to be implemented into webpack-dev-server. The way create-react-app does it is with a react-dev-utils script called openBrowser. Importing this function into a webpack after function with the parameter of the host and port, works perfectly.

// webpack.config.js or webpack.config.babel.js
import openBrowser from "react-dev-utils/openBrowser";
...
devServer: { ..., after: () => { openBrowser("http://localhost:8080"); }, ... }

With one other caveat, the .applescript file needs to be copied into the root of your project. Information about that script and where to find these files here: https://stackoverflow.com/questions/48913566/how-does-create-react-app-re-use-an-existing-browser-tab-after-running-npm-run/48915952

fixed it

@white-than-wood
Copy link

white-than-wood commented Jun 5, 2022

It seems to only apply to the mac platform, and create-react-app does the same: https://github.com/facebook/create-react-app/blob/25184c4e91ebabd16fe1cde3d8630830e4a36a01/packages/react-dev-utils/openBrowser.js#L65-L86

@alexander-akait
Copy link
Member

Yes PR welcome

@hcw2175
Copy link

hcw2175 commented Oct 31, 2022

Hey,I fount it work for me in webpack 5 like this:

// you could install react-dev-utils
import openBrowser from "react-dev-utils/openBrowser";

// webpack devServer config
{
  devServer: {
    host: '0.0.0.0',
    port: 8080,
    hot: false,
    onListening: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }
      const addr = devServer.server.address();
      openBrowser(`http://${addr.address}:${addr.port}`);
    },
  }
}

good luck

@tarunsankhla
Copy link

is the issue closed?

@alexander-akait
Copy link
Member

No

@DYW972
Copy link

DYW972 commented Feb 9, 2025

Yo!

After going through all the suggestions, I came across a solution that works for me.
Note that I’m using Firefox Developer Edition on a Linux Ubuntu machine.

Here’s what I did to make it work:

  1. Create a directory named webpack at the root of your project.
  2. Inside the webpack directory, create another directory named scripts.
  3. Inside the scripts directory, create a shell script file (let’s call it lookup_tabs_names.sh).
  4. Add the following code:
#!/bin/bash

tabName=$1
found=false
window_ids=()
tab_titles=()

# Search for browser by name and store ID in an array
window_ids+=("$(xdotool search --name "Firefox Developer Edition")")

for windowID in "${window_ids[@]}"; do
  # Activate browser window
  xdotool windowactivate --sync "$windowID"
  # Get the initial tab title
  initial_tab_title=$(xdotool getactivewindow getwindowname | awk -F '' '{print $1}')
  tab_titles+=("$initial_tab_title")

  # Cycle through tabs and get their titles
  while true; do
      # Switch to the next tab
      xdotool key --clearmodifiers ctrl+Tab
      sleep 0.1  # Wait for the tab to switch

      # Get the current tab title
      current_tab_title=$(xdotool getwindowfocus getwindowname | awk -F '' '{print $1}')

      # Trim whitespace and convert to lowercase
      current_tab_title=$(echo "${current_tab_title}" | xargs)
      initial_tab_title=$(echo "${initial_tab_title}" | xargs)
      tabName=$(echo "${tabName}" | xargs)

      # Check if the current tab matches the one we need
      if [[ "${current_tab_title,,}" == "${tabName,,}" ]]; then
          found=true
          xdotool key --window "$current_tab_title" "ctrl+r"
          break
      fi

      # Check if we've cycled back to the initial tab
      if [[ "${current_tab_title,,}" == "${initial_tab_title,,}" ]]; then
        found=false
        break
      fi
  done

  if $found; then
    break
  fi
done

# Output the result
echo $found
  1. Inside the scripts directory, create another shell script named webpack_dev_server_tab_manager.sh.
  2. Add the following code:
#!/bin/bash

# Main script
browser=$1
tabName=$2

# Check if a browser is specified
if [[ -z $browser ]]; then
  echo "Please specify the browser: chrome, firefox, or another browser name."
  exit 1
fi

# Check if the specified browser is running
if ! pgrep -x "$browser" > /dev/null; then
  echo false
  exit 0
fi

# Look for the tab running Webpack DevServer in the specified browser
result=$(bash ./webpack/scripts/lookup_tab_with_url.sh "$tabName")
echo "$result"
  1. Inside the webpack directory, create a new directory called middlewares.
  2. Add the following code:
const { exec } = require('child_process');

function openBrowserMiddleware() {
  return new Promise((resolve) => {
    const browser = 'firefox-bin'; // 'firefox', 'chrome', or the name of your browser
    const tabTitle = 'Webpack React TS';
    
    exec(`bash ./webpack/scripts/webpack_devserver_tab_manager.sh "${browser}" "${tabTitle}"`, (error, stdout, stderr) => {
      if (error) {
        console.error(`Error executing script: ${error.message}`);
        resolve(false);
        return;
      }
      if (stderr) {
        console.error(`Script stderr: ${stderr}`);
      }
      resolve(stdout.trim() === 'true');
    });
  });
}

module.exports = openBrowserMiddleware;
  1. Inside your webpack.config.js, as mentioned by @hcw2175, add the following code:
const openBrowser = require('react-dev-utils/openBrowser');
const openBrowserMiddleware = require('./webpack/middlewares/open_browser_middleware');

// Webpack DevServer configuration
{
  devServer: {
    open: false,
    onListening: async function (devServer) {
      const { port } = devServer.server.address();
      const URL = `http://localhost:${port}`;

      const isOpen = await openBrowserMiddleware();

      if (!isOpen) {
        openBrowser(URL);
      }
    },
  }
}

You'll need to adapt this setup to your specific needs (e.g., using import instead of require, installing xdotool, etc.).

Let me know what you think!

Happy Coding! 🚀

P.S. Special thanks to @hcw2175 and all the programmers whose posts I read on the web to make this work for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests