webpack-isomorphic-tools icon indicating copy to clipboard operation
webpack-isomorphic-tools copied to clipboard

anyway to define __webpack_public_path__ or cdn?

Open idangozlan opened this issue 6 years ago • 15 comments

Hi,

Is there anyway to define CDN url by variable and not trough the webpack build process?

Thanks.

idangozlan avatar Aug 17 '18 19:08 idangozlan

The only supported way is through Webpack output.publicPath.

catamphetamine avatar Aug 17 '18 19:08 catamphetamine

do you have any suggestions how to work with docker and cdn with multiple envs? since CDN will be used only for production, so that means that we need to create docker image with and without cdn if there's no any other way..

idangozlan avatar Aug 17 '18 19:08 idangozlan

I didn't work with Docker so I'm not an expert on it. Dunno.

catamphetamine avatar Aug 17 '18 19:08 catamphetamine

@idangozlan I'm facing the same issue. What I ended up doing is, I created a file with the setting of __webpack_publich_path__ and then included that on my entry point config on webpack.config.js. Similar to this: https://github.com/webpack/webpack/issues/2776#issuecomment-233808146

That takes care of the client. For the server, I had to look for an env variable I use for overwritting the cdn path and doing a replace on the assets paths. I tried adding the same script from above to the server side entry point with no luck. Where you able to solve this?

JoseInTheArena avatar Dec 06 '18 14:12 JoseInTheArena

@jarzuaga Why don't you just compile the bundle with Webpack config publicPath set to a CDN?

catamphetamine avatar Dec 06 '18 14:12 catamphetamine

@catamphetamine The problem I'm trying to solve is being able to build the application once and deploy it to different environments with different CDN paths. You can't use output.publicPath for that, as it hardcodes the CDN path on compile time. For that, you can use the __webpack_public_path__ free variable as shown here: https://webpack.js.org/guides/public-path/#on-the-fly.

I'm setting that variable on my entry points on the client side and that's working fine. However, on the server side, I couldn't find where to do this. I tried the server's entry point but all I get is a type error about __webpack_public_path__ being undefined.

JoseInTheArena avatar Dec 06 '18 15:12 JoseInTheArena

@jarzuaga I see now.

The assets source from webpack stats has shape:

module.exports = __webpack_public_path__ + \"9059f094ddb49c2b0fa6a254a6ebf2ad.jpg\"

__webpack_public_path__ is defined at:

https://github.com/catamphetamine/webpack-isomorphic-tools/blob/59aa50fbde327ec0921a9acd370868851260a4e0/source/plugin/write%20assets.js#L167-L169

write_assets() is called here:

https://github.com/catamphetamine/webpack-isomorphic-tools/blob/59aa50fbde327ec0921a9acd370868851260a4e0/source/plugin/plugin.js#L190-L193

So, basically, __webpack_public_path__ gets overwritten for each asset and then the asset source code is compiled at https://github.com/catamphetamine/webpack-isomorphic-tools/blob/59aa50fbde327ec0921a9acd370868851260a4e0/source/plugin/write%20assets.js#L478

From:

module.exports = __webpack_public_path__ + \"9059f094ddb49c2b0fa6a254a6ebf2ad.jpg\"

To:

var __webpack_public_path__ = '...'
module.exports = __webpack_public_path__ + \"9059f094ddb49c2b0fa6a254a6ebf2ad.jpg\"

And in webpack-assets.json there's already compiled value for the asset:

"https://.../9059f094ddb49c2b0fa6a254a6ebf2ad.jpg"

If you want __webpack_public_path__ not to be overridden then you can define some new option, like compileWebpackPublicPath: false, and in this case write assets.js wouldn't substitute it at compile time. But if it's not substituted then it would mean that it will throw __webpack_public_path__ is undefined when it compiles the asset. So the asset can't be compiled. Or, actually, the asset source could be modified to return:

module.exports = "__webpack_public_path__ + \"9059f094ddb49c2b0fa6a254a6ebf2ad.jpg\""

If this gets compiled then it would return:

__webpack_public_path__ + "9059f094ddb49c2b0fa6a254a6ebf2ad.jpg"

And then, when the application require()s the asset it could theoretically be compiled at run time with __webpack_public_path__ being defined. Maybe that would work, but maybe that wouldn't.

So, in short: the current handling of assets replaces __webpack_public_path__ at compile time and it excludes the cases when users would define __webpack_public_path__ at runtime. If someone wants, they can rewrite the logic for handling such "simple" assets. I guess no one would, because that could take several days. Still, I'm re-opening this issue because it is valid.

catamphetamine avatar Dec 06 '18 16:12 catamphetamine

Gotcha. Would you know if this something that could be accomplished in an "easier" way in universal-webpack? I have another app running with universal-webpack on which I need to solve for this as well. I can open an issue on that repo if you prefer.

JoseInTheArena avatar Dec 06 '18 16:12 JoseInTheArena

I guess universal-webpack is easier in a sense that it doesn't re-implement Webpack but rather is just a Webpack configuration generator. No need to open an issue of universal-webpack unless you know something is a bug.

catamphetamine avatar Dec 06 '18 16:12 catamphetamine

I see. I'm going to try it on that other application with universal-webpack and let you know how it goes. Thanks for the help.

JoseInTheArena avatar Dec 06 '18 16:12 JoseInTheArena

@jarzuaga do you have any insights :)?

idangozlan avatar Dec 11 '18 21:12 idangozlan

On webpack-isomorphic-tools is what @catamphetamine mentioned. We would need to submit a PR to modify that logic. I tried the same on universal-webpack and wasn't able to make it work either. Ultimately or the server I added an extra env variable I called CDN_URL_OVERRIDE and did a replace of CDN_URL with that new one on the assets. For the client I just did what's recommended here: https://webpack.js.org/guides/public-path/#on-the-fly

JoseInTheArena avatar Dec 11 '18 22:12 JoseInTheArena

yeah. I guess our all problem is the SSR and not the client.. anyway, if you have any PR for that, please share it with us in here :) Thanks!

idangozlan avatar Dec 12 '18 01:12 idangozlan

@jarzuaga I had a similar thought: as a hacky workaround one could write a basic Node.js script taking path to a file and replacing all CDN_URL substrings in it with a custom CDN URL and then running node process for that file (see child_process).

Example:

node ./replace-and-run.js ./path/to/bundle.js CDN_URL CUSTOM_CDN_URL

catamphetamine avatar Dec 12 '18 01:12 catamphetamine

https://gist.github.com/joshsten/971117712d920023b61699ddbc22e8ca

joshsten avatar Aug 21 '20 17:08 joshsten