Skip to content

Allow custom publicPath to be set alongside baseUrl #2525

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

Closed
lsapan opened this issue Sep 14, 2018 · 14 comments
Closed

Allow custom publicPath to be set alongside baseUrl #2525

lsapan opened this issue Sep 14, 2018 · 14 comments

Comments

@lsapan
Copy link

lsapan commented Sep 14, 2018

What problem does this feature solve?

Right now any attempt to set publicPath prevents the bundle from compiling with the following error:

Configuration Error: Avoid modifying webpack output.publicPath directly. Use the "baseUrl" option instead.

I understand why that validation is there, as it prevents accidental misconfiguration when users aren't aware of the baseUrl option. That said, there should be some way to bypass this error (or make it a warning).

My bundle gets served from my webapp which is running on a different localhost port (let's say 4000). As such, HMR attempts to load from http://localhost:4000/xxx instead of http://localhost:8080/xxx. I can't put the http://localhost:8080/ in the baseUrl because it simply tacks that onto itself (http://localhost:8080/http://localhost:8080/).

I really just need to override the publicPath for webpack, but keep the baseUrl exactly as it is. I've tried a thousand different things but there doesn't seem to be any other way around this.

What does the proposed API look like?

Either make it a warning, or add some kind of flag that says "hey, I know about baseUrl and I've set it, I just also want to set publicPath too."

Frankly, if both baseUrl and publicPath are set, it can probably be assumed that it's intentional. Maybe only display the error if publicPath is set without baseUrl.

@LinusBorg
Copy link
Member

LinusBorg commented Sep 15, 2018

Isn't devServer.public the better solution to your problem of HMR contacting the wrong backend?

Have you actually tried of changing the publicPath would solve your problem (by temporarily commenting out the codes raising the error in /node_modules/)?

The error is raised because we need to match the public path and some. Other paths we are setting, Changing it like you want to should most likely break the build.

@lsapan
Copy link
Author

lsapan commented Sep 15, 2018

Ah, shoot, I tried changing devServer.publicPath but I completely missed devServer.public. Judging from the docs that’s exactly what I need. Thanks!

@lsapan lsapan closed this as completed Sep 15, 2018
@lsapan
Copy link
Author

lsapan commented Sep 15, 2018

I stand corrected! It really seems like that should work, however, for some reason public only seems to affect the initial request (i.e. http://localhost:8080/sockjs-node/info?t=1537018718015).

After that, subsequent requests are still made to my app server (http://localhost:4000/09018356538331e29b1e.hot-update.json).

I've tried combining devServer.public and devServer.publicPath but it does not change the fact that it is still looking for the files relative to the window's location.

That said, I did try commenting out the validation code in validateWebpackConfig.js and it works with the (non dev-server) publicPath!

So this does not work:

module.exports = {
    devServer: {
        public: 'localhost:8080',
        publicPath: 'http://localhost:8080/',
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    },
}

But this does:

module.exports = {
    devServer: {
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    },
    
    configureWebpack: {
        output: {
            publicPath: 'http://localhost:8080/',
        },
    },
}

It's also worth noting that it isn't just the hot-update.json files that fail to load with the first method. Images and other static assets only load with the second option.

@lsapan lsapan reopened this Sep 15, 2018
@haoqunjiang haoqunjiang added the needs team repro We acknowledged your report and will soon try to reproduce it label Sep 17, 2018
@Aymkdn
Copy link

Aymkdn commented Sep 27, 2018

(see below for a reproduction code)

Same issue here... Modifying validateWebpackConfig.js doesn't seem to be a good idea.

The problem is that the index.js dynamically loads the dynamic components:

/******/ 	// script path function
/******/ 	function jsonpScriptSrc(chunkId) {
/******/ 		return __webpack_require__.p + "" + ({"vendors.spgrid":"vendors.spgrid","spgrid":"spgrid"}[chunkId]||chunkId) + ".js"
/******/ 	}

It uses __webpack_require__.p:

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "/";

Because I'm using a different server (https://myserver/some/path/), it tries to load the resource from this server instead of the dev server:

https://myserver/vendors.spgrid.js instead of https://localhost:18827/vendors.spgrid.js.

There is a match that is done by jsonpScriptSrc:

// {"vendors.spgrid":"vendors.spgrid","spgrid":"spgrid"}
{
  "vendors.spgrid":"vendors.spgrid",
  "spgrid":"spgrid"
}

I'm not sure where it could be defined, but maybe it could be replaced by the below (instead of using publicPath):

{
  "vendors.spgrid":"https://localhost:18827/vendors.spgrid",
  "spgrid":"https://localhost:18827/spgrid"
}

Reproduction

  1. Clone https://github.com/Aymkdn/vue-cli-issue-2525
  2. npm install
  3. npm run serve (it launchs the dev server on port 2525).
  4. Open Chrome with disabling security: chrome.exe --disable-web-security --user-data-dir --ignore-certificate-errors
  5. Go to https://codepen.io/Aymkdn/pen/ePOEaX

In the console of CodePen you'll see:

GET https://codepen.io/helloworld.js 404 ()

Instead of:

GET https://localhost:2525/helloworld.js 404 ()

It's because HelloWorld is a dynamic component (see src/App.vue)

And the simple config:

module.exports = {
  devServer:{
    https:true,
    port:2525,
    host:'localhost',
    public:'localhost:2525'
  }
}

@SwannLV
Copy link

SwannLV commented Sep 28, 2018

Same need/problem here :)

@JohnCampionJr
Copy link

I am having this issue too. Using .NET Core to proxy the vue cli server for local dev. I think another option would be to allow a relative path for the HMR, so it would work no matter which URL. Alas, putting '/' does not work.

@forforeach
Copy link

We have the same need for development environment

@ralphchristianeclipse
Copy link

    devServer: {
      headers: {
        'Access-Control-Allow-Origin': '*'
      }
    },
    baseUrl: 'http://localhost:8081/'

Setting the base url works but it seems odd

image

@haoqunjiang haoqunjiang added scope: cli-service serve and removed needs team repro We acknowledged your report and will soon try to reproduce it labels Oct 28, 2018
@asethwright
Copy link

@ralphchristianeclipse Agreed that this seems odd, but modifying vue.config.js is better than going and modifying dependency code. I had to make a small modification to get my dev and production builds working.

module.exports = {
  baseUrl: process.env.NODE_ENV === 'production'
    ? '/'
    : 'http://localhost:8080',

  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },

@wunderdojo
Copy link

I just ran into this same issue. I'm running Vue CLI inside a Vagrant box with SSL configured. Setting public and publicPath to something like https://dev.domain.com:8080 gets everything working except for hot-update.json which ignores the port and makes the request to https://dev.domain.com. Adding baseUrl solved that and everything is working correctly but baseUrl triggers the warning that it is deprecated and to use publicPath (which again, I already am). Any ideas of another way to resolve this?

@iwasingh
Copy link

iwasingh commented Jun 11, 2019

I was able to solve with both baseUrl and publicPath. I had problems with 'hot.update.json' files, for hot-reload: without baseUrl or publicPath the client pointed to localhost instead of the dev server address in the local network. In fact the webpack_require__.p address was '/' and not the ip of the server.
I'm using

"webpack": "^4.17.1",
"@vue/cli-service": "^3.0.1",

@Aymkdn
Copy link

Aymkdn commented Oct 17, 2019

With baseUrl being removed with v4.0, what would be the workaround for this need?

@lsapan
Copy link
Author

lsapan commented Nov 5, 2019

Happy to report this is no longer an issue! I just tested this on v4.0, but it looks like it was actually fixed somewhere even before that. The important difference is that devServer.public is properly causing HMR to load updates from the other port.

For reference, here's a working configuration for those who want to force the browser to load the bundle and HMR updates from http://localhost:8080/:

// Change this to match the path to your files in production (could be S3, CloudFront, etc.)
const DEPLOYMENT_PATH = '/static/'

module.exports = {
    publicPath: process.env.NODE_ENV === 'production' ? DEPLOYMENT_PATH : 'http://localhost:8080/',

    devServer: {
        public: 'localhost:8080',
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    },
}

@lsapan lsapan closed this as completed Nov 5, 2019
@AshSh
Copy link

AshSh commented Apr 11, 2020

I done it by.
Step 1: checked vue/cli version
C:\Users***>vue --version
@vue/cli 4.3.1
Step 2: Created vue.config.js just inside project in Visual studio code
Step 3: Added below code in vue.config.js
// vue.config.js
module.exports = {
publicPath: '/tkm'
}

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