jharris4 / html-webpack-tags-plugin

lets you define html tags to inject with html-webpack-plugin
MIT License
256 stars 31 forks source link

publicPath: '/' breaks the reference to CDN JS files #53

Open RareSecond opened 4 years ago

RareSecond commented 4 years ago

I hope I can explain this correctly. If something would be unclear, don't hesitate to ask further questions.

To enable local development with Webpack and React Router, you need both publicPath: '/' and historyApiFallback: true, as can be seen here

However, this makes the resulting HTML break when actually building, since it's there trying to import everything from /, even http assets.

<script type="text/javascript" src="/https://unpkg.com/react@16.8.0/umd/react.development.js"></script>
jharris4 commented 4 years ago

Hi @JDansercoer can you share more of your webpack config?

Also, please note that it is possible to set the publicPath for this plugin to a different value than the one used by webpack.

To resolve your issue, you may just want to add the following to the options for this plugin:

new HtmlWebpackTagsPlugin(
  {
    // your other options...
    publicPath: false
  }
);
RareSecond commented 4 years ago

Sorry for the late answer @jharris4.

Unfortunately, it seems I reverted my changes without stashing them, so I don't have a ready config to share with you.

I did however try setting 'publicPath' to false, but this made my main.js bundle ignore the publicPath as well. A possible solution I had, was to explicitly set publicPath: false on every tag (which are just React, ReactDOM and styled from CDN), but this seemed to be very cumbersome. I'd expect a tag that starts with http(s) to never ever listen to publicPath, no?

jharris4 commented 4 years ago

I think the usePublicPath and addPublicPath options can help you here!

Try something like this:

new HtmlWebpackTagsPlugin({
  usePublicPath: true,
  addPublicPath: (assetPath, publicPath) => {
    if (assetPath.startsWith('http')) {
      return assetPath;
    }
    return (publicPath !== '' && !publicPath.endsWith('/') && !assetPath.startsWith('/')) ? publicPath + '/' + assetPath : publicPath + assetPath;
  }
});

I'll also think about whether it might be a good idea to change the default to this behaviour...

RareSecond commented 4 years ago

Yeah, I know there's multiple ways of changing it, but just wanted to bring up that I'd expect different default behaviour for http assets :)