Skip to content

feature request: support __webpack_public_path__ for set publicPath dynamically at runtime #51

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
Zhangdroid opened this issue Nov 30, 2017 · 6 comments

Comments

@Zhangdroid
Copy link

hi~

I'm using your great work react-universal-component with extract-css-chunks-webpack-plugin and have some troubles.

We have three different test environments: dev, oa, and pre, and they have different CDN like https://devwww.examplecdn.com, https://oawww.examplecdn.com. The static files only compiled on dev environment and copy to oa ,pre and online site, so we want set publicPath(CDN) dynamically at runtime.

Webpack document said we can use __webpack_public_path__ to do this like:

// publicPath.js
// On server side configs will read process.env.ENV_TYPE and return configs for this environments
// On client side configs will read window.ENV_TYPE
import configs from 'configs';

__webpack_public_path__ = `${configs.CDN_URL}/`;

On server side , we manual add public path(it would be nice if webpack-flush-chunks can provide the public path option):

import configs from 'configs';

export default ({
  content, scripts
}) => `
<!doctype html>
<html lang="en">
<head>
</head>
<body>
  <div id="root">${content}</div>
  ...
  <script type="text/javascript">
    window.ENV_TYPE="${process.env.ENV_TYPE}";
  </script>
  ${scripts.map(name => `<script type="text/javascript" src="//${configs.CDN_URL}/${name}"></script>`)}
</body>
</html>
`;

On client side, the javascript files works fine when I using __webpack_public_path__, but css files not.

I saw extract-text-webpack-plugin have same problem but no one answer it yet. Is there anyone can help for this?

@faceyspacey
Copy link
Owner

I'm not exactly sure what to do about that, @kmcclosk might know??

@Zhangdroid
Copy link
Author

@faceyspacey I'm not familiar with how webpack works, but I just figured out how CSS files dynamically load on client side, and there are two simple ways to make this work:

  1. webpack-flush-chunks add the publicPath option that user can dynamically set on server side, rewrite publicPath that stats.json provided, then window.__CSS_CHUNKS__ will have the right path.

  2. user provide a global variable like __PUBLIC_PATH__, then babel-plugin-universal-import add it before chunk path.

// babel-plugin-universal-import/importCss.js
...
function getHref(chunkName) {
  if (typeof window === 'undefined' || !window.__CSS_CHUNKS__) return null
  return window.__PUBLIC_PATH__ ?  window.__PUBLIC_PATH__ : '' + window.__CSS_CHUNKS__[chunkName]
}

If those ways are ok, I can make a PR for this.

@faceyspacey
Copy link
Owner

#1 sounds about right. Go for it.

@Zhangdroid
Copy link
Author

@faceyspacey I just found another way: we can read __webpack_public_path__ in webpack-flush-chunks and babel-plugin-universal-import. Since __webpack_public_path__ equals the config options output.publicPath, we can use __webpack_public_path__ as publicPath instead of publicPath of stats.json(only need user set __webpack_public_path__ on both client entry and server entry).

Also, I think isn't it more reasonable that window.__CSS_CHUNKS__ just export file name of css chunks and add public path with babel-plugin-universal-import?

// webpack-flush-chunks/createApiWithCss.js
export const createCssHash = ({
  assetsByChunkName,
  publicPath
}: {
  assetsByChunkName: FilesMap,
  publicPath: string
}): CssChunksHash =>
  Object.keys(assetsByChunkName).reduce((hash, name) => {
    ...
    if (file) hash[name] = `${file}`
    return hash
  }, {})
// babel-plugin-universal-import/importCss.js
...
function getHref(chunkName) {
  if (typeof window === 'undefined' || !window.__CSS_CHUNKS__) return null
  return  __webpack_public_path__ + window.__CSS_CHUNKS__[chunkName]
}

@faceyspacey
Copy link
Owner

I don't have much time to focus on this right now, so a change that might be just fine, but could potentially break things for lots of existing users, makes me nervous without being able to analyze it myself.

Also ideally we don't touch the babel plugin.

izaakschroeder added a commit to izaakschroeder/extract-css-chunks-webpack-plugin that referenced this issue Feb 7, 2018
This means you don't need to set the `publicPath` option during setup and the loader will use webpack's native one. Resolves faceyspacey#51.
@ScriptedAlchemy
Copy link
Collaborator

Will be resolved by #71

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants