-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Add webpack 5 support to dependency-extraction-webpack-plugin #27533
Conversation
Size Change: 0 B Total Size: 1.21 MB ℹ️ View Unchanged
|
60aa47d
to
b7ef25a
Compare
@gziolo @sirreal This is still a draft. I'll make the PR official after the webpack 5 upgrade PR (#26382) that's stacked on top of this one starts working correctly (there are still some unit test failures) and actually proves that the webpack 5 support works 🙂 I also plan to update the PR description so that reviewers know what I changed and why. |
Ready for review now 🎉 |
Great work, it's very complex set of changes. It might take me some time to review but it's now on my list 👍 |
I did my best to split the patch into small independent commits and explain in detail what they do and why. Let me know if there's something that still looks confusing. |
…them explicitly Making the plugin typecheck correctly is an impossible task, due to incomplete webpack types and the need to be compatible with two versions at once. Let's write the types explicitly in a `types.d.ts` file and stop creating them at build time.
b7ef25a
to
0fe7332
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not an expert in how TypeScript integration should look like but your explanation makes a lot of sense. I would defer to @sirreal who typed this package before. Code wise, everything seems to work as necessary - all test pass. Well, at least for webpack 4 that it still uses. However, I believe that it works with webpack 5 as well since it was extracted from the PR where the upgrade is handled.
// Ignore reason: json2php is untyped | ||
// @ts-ignore | ||
const webpack = require( 'webpack' ); | ||
const { RawSource } = webpack.sources || require( 'webpack-sources' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we document it in the code:
const { RawSource } = webpack.sources || require( 'webpack-sources' ); | |
// With webpack 5 it uses `sources` field but for webpack 4 it has to fallback to `webpack-sources` package. | |
const { RawSource } = webpack.sources || require( 'webpack-sources' ); |
or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment added 🙂
… a package webpack 5 exposes `webpack-sources` as `webpack.sources` property, and makes sure that it's exactly the version that you need.
…e concatenated modules
…pe field In webpack 5, `ExternalModule` instanced no longer have the `external` boolean flag. We need to identify them by the `externalType` field presence.
In webpack 5, the default options are not applied yet when `Plugin.apply` is called. Postpone reading the `output.filename` option to the `emit` hook where the value is used. See also: https://webpack.js.org/blog/2020-10-10-webpack-5-release/#new-plugin-order
0fe7332
to
9453ab2
Compare
Fixes #26134. Adds support for webpack 5 (while keeping webpack 4 compat) to
dependency-extraction-webpack-plugin
. Spinoff from #26382. Description of changes I had to make follows.Remove type annotations, commit a hand-crafted
types.d.ts
After discussion with @sirreal in #26382 (comment), I decided to stop typechecking the plugin source code with TypeScript. Webpack types are not complete enough to make it work, and making a plugin that supports both webpack 4 and 5 is an impossible task. To make types available for consumers of the plugin, I added a hand-crafted
types.d.ts
file that describes the plugin's public interface, i.e., the constructor and its options. And it works in my Atom IDE:Stop using the
webpack-sources
package if possibleDepending on and importing the
webpack-sources
package is legacy now. A plugin can access the APIs on awebpack.sources
property of thewebpack
package export.Descend into concatenated modules
The
ExternalModule
instances can now be concatenated into a common module. We need to descend intoConcatenatedModule.modules
array to find all externals.Don't read compiler options before defaults were applied
In webpack 5, the default options are not applied yet when
Plugin.apply
is called. Postpone reading theoutput.filename
option to theemit
hook where the value is used. See also: https://webpack.js.org/blog/2020-10-10-webpack-5-release/#new-plugin-orderThen there are changes that are in unit tests only:
Change how
ExternalModule
instances are identifiedIn webpack 5,
ExternalModule
instanced no longer have theexternal
boolean flag. We need to identify them by theexternalType
field presence.Sort modules by
.identifier()
rather than implicitly by.toString()
Produces more stable sorting of the modules, preventing test failures due to implementation details changes. In webpack 5, the
toString()
output includes adebugId
value, which is an incremental counter incremented on eachModule
instantiation. Looking at.identifier()
produces more stable sorting key.Remove the
with-externs
unit test that depends on webpack internalsThere was a
with-interns
unit test that checked for behavior of twoExternalsPlugin
instances, one from config, one from this plugin, that match the same request. But this tests webpack internals rather than anything else.In webpack 4, the module factories were processed by a
SyncWaterfallHook
, using the last factory value produced by the hook for a given request. In webpack 5, the hook is anAsyncSeriesBailHook
, and it bails on the first plugin returning a valid factory.So, even if two conflicting
ExternalsPlugin
instances were declared in the same order, the behavior is different in v4 vs v5.How to test:
The full webpack 5 upgrade is stacked on top of this PR in #26382, and it builds cleanly including all unit and e2e tests.
This PR alone still uses webpack 4 with the updated
dependency-extraction-webpack-plugin
. And is also green.