Skip to content
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

Plugins used when bundling worker #70

Open
matthewwithanm opened this issue Apr 21, 2020 · 2 comments
Open

Plugins used when bundling worker #70

matthewwithanm opened this issue Apr 21, 2020 · 2 comments
Labels
question Further information is requested upstream The issue is controlled by an upstream dependency

Comments

@matthewwithanm
Copy link

According to the docs:

By default, WorkerPlugin doesn't run any of your configured Webpack plugins when bundling worker code

However, this doesn't seem to be true. Consider the following partial config:

plugins: [
  new webpack.DefinePlugin({
    _A_: JSON.stringify('this text should never appear in worker'),
  }),
  new WorkerPlugin({
    plugins: [
      new webpack.DefinePlugin({
        _B_: JSON.stringify('this text should definitely appear in worker'),
      }),
    ],
  }),
]

Given the documentation, the expectation would be that:

  • In the worker:
    • _A_ is untouched
    • _B_ is replaced with 'this text should definitely appear in worker'
  • Everywhere else:
    • _A_ is replaced with 'this text should never appear in worker'
    • _B_ is untouched

However, in all code _A_ is replaced with 'this text should never appear in worker' and _B_ is untouched.

This is apparently because the DefinePlugin is using hooks that are copied into the child compiler created by WorkerPlugin (see createChildCompiler()).

For background, my actual use case is to use ProvidesPlugin (not DefinePlugin) to replace a free variable with a different implementation (module) in workers vs elsewhere.

@developit
Copy link
Collaborator

developit commented May 3, 2020

Hi there - as you found in your research, DefinePlugin is broken in this way. This isn't an incorrect piece of documentation, it is simply a bug in Webpack's DefinePlugin. It is a sore spot though (and one I've run into personally), I just don't really think there's anything that can be done outside of webpack core to correct it.

In terms of a solution, if you're using Babel, it's relatively easy to do replacement in Babel and doing so does not suffer from this issue:
https://github.com/jviide/babel-plugin-transform-replace-expressions

Another solution is to leverage the fact that DefinePlugin (and its derivatives like ProvidesPlugin) only "bleed" their values downward (into child compilers). Knowing this, if there's a way for you to provide the replacement only in the worker, it won't affect the main thread code:

plugins: [
  new WorkerPlugin({
    plugins: [
      new webpack.DefinePlugin({
        _A_: JSON.stringify('this text should definitely appear in worker'),
      }),
    ],
  }),
]

I've found that in many cases this ends up being sufficient (though perhaps not optimal), since I can handle it in my code as:

// if _A_ is defined, use it. Otherwise fall back to our inline main thread value.
// in the production worker bundle, this conditional is removed.
const MY_STRING = typeof _A_ != 'undefined' ? _A_ : 'this text should never appear in worker';

@developit developit added the question Further information is requested label May 3, 2020
@developit developit added the upstream The issue is controlled by an upstream dependency label Aug 11, 2020
@matthewwithanm
Copy link
Author

Thanks for the suggestions, but my actual use case is to use ProvidesPlugin (not DefinePlugin) so I don't think that would work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested upstream The issue is controlled by an upstream dependency
Projects
None yet
Development

No branches or pull requests

2 participants