Vue-cli: Custom sockPath for sockjs-node (HMR) partially fails

Created on 6 Aug 2019  路  10Comments  路  Source: vuejs/vue-cli

Version

3.10.0

Reproduction link

https://github.com/fleebzz/vue-cli-sockjs-path-issue

Environment info

System:
    OS: Linux 4.9 Debian GNU/Linux 9 (stretch) 9 (stretch)
    CPU: (2) x64 Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz
  Binaries:
    Node: 12.7.0 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.10.0 - /usr/local/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: Not Found
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0 
    @vue/babel-plugin-transform-vue-jsx:  1.0.0 
    @vue/babel-preset-app:  3.10.0 
    @vue/babel-preset-jsx:  1.1.0 
    @vue/babel-sugar-functional-vue:  1.0.0 
    @vue/babel-sugar-inject-h:  1.0.0 
    @vue/babel-sugar-v-model:  1.0.0 
    @vue/babel-sugar-v-on:  1.1.0 
    @vue/cli-overlay:  3.10.0 
    @vue/cli-plugin-babel: ^3.10.0 => 3.10.0 
    @vue/cli-plugin-eslint: ^3.10.0 => 3.10.0 
    @vue/cli-service: ^3.10.0 => 3.10.0 
    @vue/cli-shared-utils:  3.10.0 
    @vue/component-compiler-utils:  2.6.0 (3.0.0)
    @vue/preload-webpack-plugin:  1.1.1 
    @vue/web-component-wrapper:  1.2.0 
    eslint-plugin-vue: ^5.0.0 => 5.2.3 (4.7.1)
    vue: ^2.6.10 => 2.6.10 
    vue-eslint-parser:  5.0.0 (2.0.3)
    vue-hot-reload-api:  2.3.3 
    vue-loader:  15.7.1 
    vue-style-loader:  4.1.2 
    vue-template-compiler: ^2.6.10 => 2.6.10 
    vue-template-es2015-compiler:  1.9.1 
  npmGlobalPackages:
    @vue/cli: 3.10.0

Steps to reproduce

  1. Clone the repo
  2. Run yarn serve
  3. Browse http://localhost:9090/sub-folder
  4. Observe in Network pan two requests for sockjs-node :

    • GET http://localhost:9090/sub-folder/sockjs-node/info which succeeds

    • GET http://localhost:9090/sockjs-node/info wich fails

What is expected?

Only one /info request

What is actually happening?

Two requests to sockjs-node/info with one ignoring the custom socket path


Second request should not happen and throws a lot of 404 errors in console.

The error seems to come from vue-cli and not from webpack-dev-server. See following repository with same behavior but without vue-cli and only webpack-dev-server, it works : https://github.com/fleebzz/webpack-sockjs-path-issue.

contribution welcome hacktoberfest intend to implement

Most helpful comment

Workaround:

devServer: {
  public: '0.0.0.0',
  sockPath: '/mysockjs'
},

configureWebpack: {
  plugins: [
    {
      apply: compiler => {
        compiler.hooks.entryOption.tap('entry', () => {
          const clients = compiler.options.entry.app
          for (const index in clients) {
            if (clients[index].match(/sockjs-node/)) {
              clients[index] = clients[index].replace('0.0.0.0/sockjs-node', '0.0.0.0&sockPath=/mysockjs')
            }
          }
        })
      }
    }
  ],
...

All 10 comments

馃 Please ? Anybody ?

+1 on this and also doesn't use the sockHost available on dev-server

+1 - only first query go to devServer.sockPath (/admin/sockjs-node/info in my case). others go to /sockjs-node/info

Workaround:

devServer: {
  public: '0.0.0.0',
  sockPath: '/mysockjs'
},

configureWebpack: {
  plugins: [
    {
      apply: compiler => {
        compiler.hooks.entryOption.tap('entry', () => {
          const clients = compiler.options.entry.app
          for (const index in clients) {
            if (clients[index].match(/sockjs-node/)) {
              clients[index] = clients[index].replace('0.0.0.0/sockjs-node', '0.0.0.0&sockPath=/mysockjs')
            }
          }
        })
      }
    }
  ],
...

Thanks @kakenbok - I have confirmed that the following workaround inspired by you resolves the issue for me.

// vue.config.js
const publicHost = 'foo.localhost';
const publicPath = '/subdir/';
const sockPath = `${publicPath}sockjs-node`;

module.exports = {
  devServer: {
    // ...
    public: publicHost,
    sockPath // broken in vue-cli - see workaround below
  },
  publicPath,
  // ...
  configureWebpack: (cfg) => {
    // TEMPORARY workaround for https://github.com/vuejs/vue-cli/issues/4400 and https://github.com/vuejs/vue-cli/issues/5372
    cfg.plugins.push({
      apply: (compiler) => {
        compiler.hooks.entryOption.tap('entry', () => {
          const clients = compiler.options.entry.app;
          for (const index in clients) {
            if (clients[index].endsWith(`${publicHost}/sockjs-node`)) {
              clients[index] = clients[index].replace(`${publicHost}/sockjs-node`, `${publicHost}&sockPath=${sockPath}`);
            }
          }
        });
      }
    });
  }
};

With those workarounds I get the web socket to connect, but hot reloading isn't working anyways. Has anyone else had similar issues?

Note: I was using kakenbok's fix for a while, but my reverse proxies were misconfigured. Once I was able to have the websocket connections go through, my webpack chunk .js files would serve the index.html file but only on page load. (If you used wget or even just resent the request in devtools it would serve the proper file.)

If you get strange behaviour where your webpack chunks aren't being delivered properly, best to try blocking the websockets and refreshing to see if it's related.

Interestingly, my hot-reload was working when the sockjs websockets failed to upgrade (normal http was still passing through), but now that the sockets connect, my site breaks due to the webpack issues mentioned in my last comment

vue.config.js

module.exports = {
    publicPath: "/testapp/",
    devServer: {
        // historyApiFallback: false,
        disableHostCheck: true,
        public: "0.0.0.0",
        sockPath: "/testapp/sockjs-node/",
        port: 80,
    },
    configureWebpack: {
        plugins: [
            {
                apply: compiler => {
                    compiler.hooks.entryOption.tap("entry", () => {
                        const clients = compiler.options.entry.app;
                        for (const index in clients) {
                            if (clients[index].match(/sockjs-node/)) {
                                clients[index] = clients[index].replace(
                                    "0.0.0.0/sockjs-node",
                                    "0.0.0.0&sockPath=/testapp/sockjs-node/",
                                );
                            }
                        }
                    });
                },
            },
        ],
    },
}

apache (my toplevel proxy) conf

    ProxyPass /testapp/sockjs-node/ ws://myNGINX/sockjs-node/
    ProxyPassReverse /testapp/sockjs-node/ ws://myNGINX/sockjs-node/

    ProxyPass /testapp/ http://myNGINX/
    ProxyPassReverse /testapp/ http://myNGINX/

nginx/conf.d/default.conf (myNGINX host)

    location ^~ / {
        proxy_pass http://myVueApp:80/testapp/; # publicPath    
        proxy_http_version 1.1;
        proxy_redirect     off;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection "Upgrade";
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        # add_header         X-Content-Type-Options nosniff; # When .js files redirect to .html, we want to know.
    }

Normal page load, when trying to get webpack chunk 7.js instead is served index.html (not good)

[12/May/2020:17:44:34 +0000] remote:"172.30.0.5" user:"-" request:"GET /testapp/js/7.js HTTP/1.1" status:200 bytes:2766 referer:"https://localhost/testapp/en/tezt" server:"localhost" upstream:"192.168.16.2:80 (test-cdp-app2-vue)" response_time:"0.002 (0.004)"

Note that the request:"GET /testapp/js/7.js HTTP/1.1" here is for /testapp/ instead of being the root of the container

Manual request, serves proper 7.js file (good)

[12/May/2020:17:44:43 +0000] remote:"172.30.0.5" user:"-" request:"GET /js/7.js HTTP/1.1" status:200 bytes:17339 referer:"https://localhost/testapp/en/tezt" server:"localhost" upstream:"192.168.16.2:80 (test-cdp-app2-vue)" response_time:"0.001 (0.000)"

request:"GET /js/7.js HTTP/1.1"

Presumably this means that somewhere along the line, the chunk is being requested at
https://localhost/testapp/testapp/js/7.js
instead of
https://localhost/testapp/js/7.js

So I'll have to either add more exceptions to my dev nginx conf or find out why it's doubling up my path

EDIT:
For now, I've simply removed the sockjs-node rules in the apache config.
I get Firefox can鈥檛 establish a connection to the server at wss://localhost/testapp/sockjs-node/983/5tge5jvp/websocket. errors, but the hot-reload works and it's only relevent in dev anyways. I'll live with it :/

DANKE (thanks) very much!!! @AlbertBrand + @sodatea

Was this page helpful?
0 / 5 - 0 ratings