Nous avons déprécié et supprimé CommonsChunkPlugin, et nous l'avons remplacé par un ensemble de valeurs par défaut et une API facilement surchargeable appelée optimization.splitChunks
.
webpack.optimize.CommonsChunkPlugin has been removed,
please use config.optimization.splitChunks instead.
Déprécié
Vous n'avez plus besoin d'utiliser ces plugins :
DedupePlugin a également été supprimé dans la version 4.
NoEmitOnErrorsPlugin -> optimization.noEmitOnErrors (activé par défaut en mode production) ModuleConcaténationPlugin -> optimization.concatenateModules (activé par défaut en mode prod) NamedModulesPlugin -> optimization.namedModules (activé par défaut en mode dev)
Recommandations pour webpack 4
Utilisez mini-css-extract-plugin
au lieu de text-extract-plugin
. Utilisez webpack-bundle-analyzer
pour analyser votre production groupée de manière graphique.
Les scripts d'entrée sont de véritables "scripts d'entrée" dans votre application. N'ajoutez pas explicitement les fichiers du vendeur à l'application. entry:
en webpack.config.js
. Les applications SPA n'ont qu'une seule entrée et les applications multi-pages comme les applications classiques. ASP.NET MVC
Les applications ont plusieurs points d'entrée. Webpack construira un graphe de dépendances à partir de vos scripts d'entrée et générera des paquets optimisés pour votre application.
Si vous souhaitez migrer à partir d'une version antérieure de webpack, il est préférable de vérifier le fichier guide de migration
Le Tree Shaking (élimination des codes morts) n'est activé qu'en mode production.
Webpack 4, la nouvelle façon de regrouper les ressources
( Vous devez retirer votre pensée CommonsChunkPlugin de votre tête. )
! !! Pendant ce temps, la doc de webpack a été mise à jour, une section SplitChunks
a été ajouté ! !!
Il suit une nouvelle philosophie :
Webpack 4 effectue désormais des optimisations automatiques par défaut. Il analyse votre graphe de dépendances et crée des paquets optimaux (sortie), en fonction des conditions suivantes :
- Un nouveau chunk peut être partagé OU les modules sont issus du dossier node_modules
- Le nouveau morceau serait plus grand que 30kb (avant min+gz)
- Nombre maximal de requêtes parallèles lors du chargement de morceaux à la demande <= 5
- Nombre maximal de requêtes parallèles au chargement initial de la page <= 3
Tout cela peut être modifié à l'aide du SplitChunksPlugin ! ( voir la documentation de SplitChunksPlugin )
Une explication plus détaillée sur la façon d'utiliser le nouveau optimization.splitChunks
API.
CommonsChunkPlugin a été supprimé car il présente de nombreux problèmes :
- Cela peut entraîner le téléchargement de plus de code que nécessaire.
- C'est inefficace sur les morceaux asynchrones.
- Il est difficile à utiliser.
- La mise en œuvre est difficile à comprendre.
Le SplitChunksPlugin possède également d'excellentes propriétés :
- Il ne télécharge jamais les modules inutiles (tant que vous n'imposez pas la fusion des morceaux par le nom).
- Il fonctionne aussi efficacement sur les morceaux asynchrones.
- Elle est activée par défaut pour les morceaux asynchrones.
- Il gère le fractionnement des fournisseurs avec des blocs de fournisseurs multiples.
- Il est plus facile à utiliser
- Il ne repose pas sur des bidouillages de graphes de morceaux.
- Principalement automatique
--> Source
En ce qui concerne votre problème vous voulez diviser tous les deps de l'entrée 1 et de l'entrée 2 en paquets séparés.
optimization: {
splitChunks: {
cacheGroups: {
"entry1-bundle": {
test: /.../, // <-- use the test property to specify which deps go here
chunks: "all",
name: "entry1-bundle",
/** Ignore minimum size, minimum chunks and maximum requests and always create chunks for this cache group */
enforce: true,
priority: .. // use the priority, to tell where a shared dep should go
},
"entry2-bundle": {
test: /..../, // <-- use the test property to specify which deps go here
chunks: "all",
name: "entry2-bundle",
enforce: true,
priority: ..
}
}
}
},
Si vous n'ajoutez pas l'entrée optimization:splitChunks, l'entrée réglage par défaut est le suivant :
splitChunks: {
chunks: 'async',
minSize: 30000,
minRemainingSize: 0,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 6,
maxInitialRequests: 4,
automaticNameDelimiter: '~',
automaticNameMaxLength: 30,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
Vous pouvez définir l'optimisation.splitChunks.cacheGroups. par défaut à false pour désactiver le par défaut groupe de cache, idem pour vendeurs groupe de cachettes !
Voici d'autres Exemples de configuration de SplitChunks avec une explication.
Mise en œuvre d'interfaces actualisées pour SplitChunksOptions
, CachGroupOptions
y Optimization
peuvent être trouvés aquí .
Les définitions d'interface ci-dessous peuvent ne pas être exactes à 100%, mais elles sont bonnes pour un aperçu simple :
SplitChunksOptions
interface
interface SplitChunksOptions {
/** Select chunks for determining shared modules (defaults to \"async\", \"initial\" and \"all\" requires adding these chunks to the HTML) */
chunks?: "initial" | "async" | "all" | ((chunk: compilation.Chunk) => boolean);
/** Minimal size for the created chunk */
minSize?: number;
/** Minimum number of times a module has to be duplicated until it's considered for splitting */
minChunks?: number;
/** Maximum number of requests which are accepted for on-demand loading */
maxAsyncRequests?: number;
/** Maximum number of initial chunks which are accepted for an entry point */
maxInitialRequests?: number;
/** Give chunks created a name (chunks with equal name are merged) */
name?: boolean | string | ((...args: any[]) => any);
/** Assign modules to a cache group (modules from different cache groups are tried to keep in separate chunks) */
cacheGroups?: false | string | ((...args: any[]) => any) | RegExp | { [key: string]: CacheGroupsOptions };
}
CacheGroupsOptions
interface :
interface CacheGroupsOptions {
/** Assign modules to a cache group */
test?: ((...args: any[]) => boolean) | string | RegExp;
/** Select chunks for determining cache group content (defaults to \"initial\", \"initial\" and \"all\" requires adding these chunks to the HTML) */
chunks?: "initial" | "async" | "all" | ((chunk: compilation.Chunk) => boolean);
/** Ignore minimum size, minimum chunks and maximum requests and always create chunks for this cache group */
enforce?: boolean;
/** Priority of this cache group */
priority?: number;
/** Minimal size for the created chunk */
minSize?: number;
/** Minimum number of times a module has to be duplicated until it's considered for splitting */
minChunks?: number;
/** Maximum number of requests which are accepted for on-demand loading */
maxAsyncRequests?: number;
/** Maximum number of initial chunks which are accepted for an entry point */
maxInitialRequests?: number;
/** Try to reuse existing chunk (with name) when it has matching modules */
reuseExistingChunk?: boolean;
/** Give chunks created a name (chunks with equal name are merged) */
name?: boolean | string | ((...args: any[]) => any);
}
Optimization
Interface
interface Optimization {
/**
* Modules are removed from chunks when they are already available in all parent chunk groups.
* This reduces asset size. Smaller assets also result in faster builds since less code generation has to be performed.
*/
removeAvailableModules?: boolean;
/** Empty chunks are removed. This reduces load in filesystem and results in faster builds. */
removeEmptyChunks?: boolean;
/** Equal chunks are merged. This results in less code generation and faster builds. */
mergeDuplicateChunks?: boolean;
/** Chunks which are subsets of other chunks are determined and flagged in a way that subsets don’t have to be loaded when the bigger chunk has been loaded. */
flagIncludedChunks?: boolean;
/** Give more often used ids smaller (shorter) values. */
occurrenceOrder?: boolean;
/** Determine exports for each module when possible. This information is used by other optimizations or code generation. I. e. to generate more efficient code for export * from. */
providedExports?: boolean;
/**
* Determine used exports for each module. This depends on optimization.providedExports. This information is used by other optimizations or code generation.
* I. e. exports are not generated for unused exports, export names are mangled to single char identifiers when all usages are compatible.
* DCE in minimizers will benefit from this and can remove unused exports.
*/
usedExports?: boolean;
/**
* Recognise the sideEffects flag in package.json or rules to eliminate modules. This depends on optimization.providedExports and optimization.usedExports.
* These dependencies have a cost, but eliminating modules has positive impact on performance because of less code generation. It depends on your codebase.
* Try it for possible performance wins.
*/
sideEffects?: boolean;
/** Tries to find segments of the module graph which can be safely concatenated into a single module. Depends on optimization.providedExports and optimization.usedExports. */
concatenateModules?: boolean;
/** Finds modules which are shared between chunk and splits them into separate chunks to reduce duplication or separate vendor modules from application modules. */
splitChunks?: SplitChunksOptions | false;
/** Create a separate chunk for the webpack runtime code and chunk hash maps. This chunk should be inlined into the HTML */
runtimeChunk?: boolean | "single" | "multiple" | RuntimeChunkOptions;
/** Avoid emitting assets when errors occur. */
noEmitOnErrors?: boolean;
/** Instead of numeric ids, give modules readable names for better debugging. */
namedModules?: boolean;
/** Instead of numeric ids, give chunks readable names for better debugging. */
namedChunks?: boolean;
/** Defines the process.env.NODE_ENV constant to a compile-time-constant value. This allows to remove development only code from code. */
nodeEnv?: string | false;
/** Use the minimizer (optimization.minimizer, by default uglify-js) to minimize output assets. */
minimize?: boolean;
/** Minimizer(s) to use for minimizing the output */
minimizer?: Array<Plugin | Tapable.Plugin>;
/** Generate records with relative paths to be able to move the context folder". */
portableRecords?: boolean;
}
}