fix(@ngtools/webpack): give higher priority to ivy-specific entry-points

When Ivy is enabled in an app, the app's dependencies are processed by
ngcc (the Angular compatibility compiler), which will generate new
Ivy-compatible entry-points in each package. To allow webpack find those
entry-points, it will add references to them in `package.json`, named
after the original property with the `_ivy_ngcc` suffix. So, for
example, `es2015` and `module` will become `es2015_ivy_ngcc` and
`module_ivy_ngcc`.

Previously, the `mainFields` passed to webpack would give higher
priority to an Ivy entry-point compared to the corresponding non-ivy
entry-point but not compared to other entry-points. For example,
`es2015, module` would becode
`es2015_ivy_ngcc, es2015, module_ivy_ngcc, module`. This could mean that
`es2015` would be preferred over `module_ivy_ngcc`, even though the
former is probably not Ivy-ready. Generally, if `es2015` exists and has
a higher priority than `module`, then `es2015_ivy_ngcc` would be
generated before (or instead of) `module_ivy_ngcc`, but this can be
changed using an ngcc configuration file (`ngcc.config.js`).

This commit fixes this by ensuring that any `_ivy_ngcc` entry-point is
considered before any of the original entry-points in the `mainFields`
list.

NOTE:
While it is possible that a format is Ivy-compatible without bhaving an
`_ivy_ngcc` suffix (e.g. if the user does a manual ngcc pass without
`--create-ivy-entry-points`), it is quite unlikely to happen and even if
it does, choosing a different format should be OK.
This commit is contained in:
George Kalpakas 2020-04-10 18:10:07 +03:00 committed by Douglas Parker
parent 710cf5656e
commit c7c574affb

View File

@ -911,18 +911,18 @@ export class AngularCompilerPlugin {
// When Ivy is enabled we need to add the fields added by NGCC // When Ivy is enabled we need to add the fields added by NGCC
// to take precedence over the provided mainFields. // to take precedence over the provided mainFields.
// NGCC adds fields in package.json suffixed with '_ivy_ngcc' // NGCC adds fields in package.json suffixed with '_ivy_ngcc'
// Example: module -> module__ivy_ngcc // Example: module -> module_ivy_ngcc
// tslint:disable-next-line:no-any // tslint:disable-next-line:no-any
(compiler as any).resolverFactory.hooks.resolveOptions (compiler as any).resolverFactory.hooks.resolveOptions
.for('normal') .for('normal')
// tslint:disable-next-line:no-any // tslint:disable-next-line:no-any
.tap('WebpackOptionsApply', (resolveOptions: any) => { .tap('WebpackOptionsApply', (resolveOptions: any) => {
const mainFields = (resolveOptions.mainFields as string[]) const originalMainFields: string[] = resolveOptions.mainFields;
.map(f => [`${f}_ivy_ngcc`, f]); const ivyMainFields = originalMainFields.map(f => `${f}_ivy_ngcc`);
return { return {
...resolveOptions, ...resolveOptions,
mainFields: flattenArray(mainFields), mainFields: [...ivyMainFields, ...originalMainFields],
}; };
}); });
} }