Skip to content

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

Open

Description

@elrumordelaluz
  • 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

Activity

  1. alexander-akait commented on May 7, 2018

    @alexander-akait
  2. elrumordelaluz commented on May 7, 2018

    @elrumordelaluz
    Author
  3. alexander-akait commented on May 7, 2018

    @alexander-akait
  4. elrumordelaluz commented on May 7, 2018

    @elrumordelaluz
    Author
  5. alexander-akait commented on May 7, 2018

    @alexander-akait
    Member
  6. flekschas commented on Nov 1, 2018

    @flekschas

    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.

  7. alexander-akait commented on Nov 1, 2018

    @alexander-akait
    Member

    feel free to send a PR

  8. flekschas commented on Nov 1, 2018

    @flekschas

    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. :)

  9. alexander-akait commented on Nov 1, 2018

    @alexander-akait
    Member

    @flekschas feel free to send a PR

  10. 1 remaining item

  11. speaud commented on Feb 26, 2020

    @speaud

    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.

  12. alexander-akait commented on Mar 31, 2020

    @alexander-akait
    Member

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

  13. Akiyamka commented on May 15, 2020

    @Akiyamka

    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.

  14. ckken commented on Jun 29, 2020

    @ckken

    mark

  15. kaspar-p commented on Jul 14, 2020

    @kaspar-p

    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

  16. Akiyamka commented on Jul 16, 2020

    @Akiyamka

    @Kaspar78 it's work only for mac platform

  17. ckken commented on Jul 17, 2020

    @ckken

    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

  18. added a commit that references this issue on Jul 30, 2020
  19. white-than-wood commented on Jun 5, 2022

    @white-than-wood
  20. alexander-akait commented on Jun 5, 2022

    @alexander-akait
    Member

    Yes PR welcome

  21. hcw2175 commented on Oct 31, 2022

    @hcw2175

    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

  22. tarunsankhla commented on Apr 20, 2024

    @tarunsankhla

    is the issue closed?

  23. alexander-akait commented on Apr 22, 2024

    @alexander-akait
    Member

    No

  24. yohDone commented on Feb 9, 2025

    @yohDone

    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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions