Maison >interface Web >js tutoriel >À propos de l'utilisation de la mise en cache du webpack et du packaging indépendant

À propos de l'utilisation de la mise en cache du webpack et du packaging indépendant

巴扎黑
巴扎黑original
2017-08-06 15:07:031181parcourir

Cet article présente principalement l'utilisation avancée du webpack - mise en cache et packaging indépendant. L'éditeur pense que c'est plutôt bien, je vais donc le partager avec vous maintenant et le donner comme référence. Suivons l'éditeur et jetons un coup d'œil.

Cet article présente l'utilisation avancée de webpack - l'utilisation de la mise en cache et du packaging indépendant. Je le partage avec vous. J'espère qu'il sera utile à tout le monde.

Jetons d'abord un coup d'œil aux bases Configuration du Webpack :


var path = require('path');
 
module.exports = {
 entry: './src/index.js',
 output: {
  filename: 'bundle.js',
  path: path.resolve(__dirname, 'dist')
 }
}
Introduction de la bibliothèque lodash dans index.js :


src/index.js :


import _ from 'lodash';
 
 function component() {
  var element = document.createElement('p');
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
 
  return element;
 }
 
 document.body.appendChild(component());
Après l'empaquetage, un seul bundle.js sera généré. Dans ce cas, chaque fois que vous souhaitez charger un fichier de ressources, le navigateur chargera la bibliothèque lodash qui ne changera pas du tout, donc très inefficace.


Étant donné que chaque fois que vous visitez le navigateur, le navigateur téléchargera à nouveau les ressources. Étant donné que le réseau peut être lent à obtenir des ressources, la page peut ne pas être chargée pendant une longue période, ce qui est inefficace. et peu convivial, le navigateur mettra donc en cache les ressources pour éviter d'avoir à les récupérer sur le réseau à chaque fois que vous y accédez.


Cependant, en raison de la mise en cache du navigateur, de nouveaux problèmes surgiront. Si nous ne modifions pas le nom de fichier de la ressource lors du déploiement de la version, le navigateur peut penser qu'elle n'a pas été mise à jour et qu'elle l'utilisera. sa version en cache.


De cette façon, nous devons résoudre deux problèmes :

Tout d'abord, séparer les fichiers empaquetés. Deuxièmement, résolvez le problème de mise en cache.


const path = require('path');
const webpack = require('webpack');
 
module.exports = {
 entry: {
  common: ['lodash'],
  app: './src/index.js'
 },
 output: {
  filename: '[name].[hash].js',
  path: path.resolve(__dirname, 'dist')
 },
 plugins: [
  new webpack.optimize.CommonsChunkPlugin({
   name: 'common' // 指代index.js引入的lodash库
  })
 ]
}
Principaux changements :

  • Ajouter un plug-in : CommonsChunkPlugin, extraire la bibliothèque importée, renommer et mettre en œuvre la séparation des codes.

  • Un hachage est ajouté au nom dans la sortie Après chaque package, la valeur de hachage est différente, ce qui résout le problème de la mise en cache du navigateur.

Résultat : index.js est empaqueté sous app.[hash].js, et lodash introduit par index.js est empaqueté sous common.[hash].js. Cela résout le problème du cache du navigateur et réalise la séparation du code de ressource statique et du code source, mais de nouveaux problèmes surviennent à nouveau.

Après le premier package (notez le nom sous la colonne Actif) :

Chaque fois que nous modifions le code source, emballez-le à nouveau, pas seulement indexez génération La valeur de hachage de app.[hash].js a changé,

et la valeur de hachage de common.[hash].js est la même que la valeur de hachage de app et a également changé (vous pouvez le tester par vous-même, le conditionner une fois avec webpack, modifier index.js et le conditionner à nouveau).

Ce n'est pas le résultat que nous souhaitons. Bien que le changement de hachage du code source résout le problème du navigateur utilisant la version mise en cache, si la valeur de hachage de common.js change également, le navigateur le fera également. demander le code statique commun qui ne changera pas à chaque fois, ce qui gaspille toujours les ressources du réseau et est très inefficace.

Remarque : ce cas sera empaqueté plusieurs fois et trop de fichiers indésirables seront générés dans le répertoire dist. En utilisation réelle, le plug-in CleanWebpackPlugin est utilisé.


Copier le code Le code est le suivant :

new CleanWebpackPlugin(['dist']) // Ajouter au tableau de plugins pour chacun Avant l'empaquetage, tous les fichiers précédemment empaquetés dans le dossier d'empaquetage seront effacés.

Si l'index est modifié, seule la valeur de hachage de l'application générée changera, mais la valeur de hachage du commun ne changera pas, alors notre objectif peut être atteint, qui peut à la fois mettre en cache la bibliothèque et identifiez la source des modifications apportées au fichier.

Nous configurons comme suit : Remplacez [name].[hash].js en sortie par [name].[chunkhash].js afin que chaque fichier génère une valeur de hachage unique :


const path = require('path');
const webpack = require('webpack');
 
module.exports = {
 entry: {
  common: ['lodash'],
  app: './src/index.js'
 },
 output: {
  filename: '[name].[chunkhash].js',
  path: path.resolve(__dirname, 'dist')
 },
 plugins: [
  new CleanWebpackPlugin(['dist']),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'common' // 指代index.js引入的lodash库
  })
 ]
}
(Remarque : n'utilisez pas [chunkhash] dans un environnement de développement car cela augmenterait le temps de compilation. Séparez la configuration pour le mode développement et le mode production et utilisez [name].js en mode développement. Le nom du fichier est [ name].[chunkhash].js en mode production, donc si le HotModuleReplacementPlugin est utilisé à ce moment, la compilation échouera ! )


Nous après la configuration, effectuons le packaging du webpack :

chunkhash est un hachage généré en fonction du contenu du fichier. On peut voir que les valeurs de hachage générées par l'application et communes sont différentes (utilisez [nom] pour comparaison. [hash]. js).


Nous apportons des modifications aléatoires dans index.js et l'emballons à nouveau :

La chose étrange est que, bien que commun et l'application génère une valeur de hachage distincte , mais après avoir modifié index.js, la valeur de hachage de common change toujours.

原因是:为了最小化生成的文件大小,webpack使用标识符而不是模块名称,在编译期间生成标识符,并映射到块文件名,然后放入一个名为chunk manifest的JS对象中。重点就在于!!当我们使用CommonsChunkPlugin分离代码时,被分离出来的代码(本文中的lodash库,被打包为common。),会默认被移动到entry中最后一个入口进行打包(第一个入口是index.js)。重要的是,chunk manifest将随着这些被分离出来的代码共同打包!!!

由于我们更改源代码后,不但会更新app的hash值,还会生成新的映射,然后新的映射又会和资源代码一同打包,又由于chunkhash是根据内容生成hash的,那么加入了新的映射对象chunk manifest的资源代码被打包后,hash自然也会发生改变。这反过来,产生的新hash将使长效缓存失效。

那么接下来我们需要做的就是讲 manifest分离出来。这里我们利用一个CommonsChunkPlugin一个较少有人知道的功能,能够在每次修改后的构建中将manifest提取出来,通过指定entry中未用到的名称,此插件会自动将我们需要的内容提取到单独的包中。

故再额外配置一个CommonsChunkPlugin:


const path = require('path');
const webpack = require('webpack');
 
module.exports = {
 entry: {
  common: ['lodash'],
  app: './src/index.js'
 },
 output: {
  filename: '[name].[chunkhash].js',
  path: path.resolve(__dirname, 'dist')
 },
 plugins: [
  new CleanWebpackPlugin(['dist']),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'common' // 指代index.js引入的lodash库
  }),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'manifest' // 用于提取manifest
  })
 ]
}

webpack打包后:

从这里可以证明之前所说的manifest被打包进了common!!!仔细看之前的图:common的Size都是547kb,到这里common大小是541kb 而manifest大小正好为5.85kb,加起来正好为547kb。

然后我们修改index.js再次打包:

从这里可以发现!!我们修改了源代码,common的hash值已经不再发生改变了!到这里可以达到我们不缓存源代码缓存资源文件的目的了。

但是可别高兴得太早!!我们做了一个很小的修改,交换了entry中 app 和 common的顺序(对比上一个代码段):


const path = require('path');
const webpack = require('webpack');
 
module.exports = {
 entry: {
  app: './src/index.js',
  common: ['lodash']
 },
 output: {
  filename: '[name].[chunkhash].js',
  path: path.resolve(__dirname, 'dist')
 },
 plugins: [
  new CleanWebpackPlugin(['dist']),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'common' // 指代index.js引入的lodash库
  }),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'manifest' // 用于提取manifest
  })
 ]
}

打包后:

这里发现对比上一张图片发现,common的hash值又发生改变了!!而且根本没有更改index.js的内容app的hash也变了,只是换了一下顺序而已!

大家注意看本张图与上一张图的模块解析顺序([1],[2],[3]...之后所对应的模块)。发现上一张图,lodash第一个解析,而现在lodash最后一个解析。

这就是hash更变的原因:这是因为每个module.id 会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变,所以hash值也会发生变化。

有人可能会决定,一般我们都不会更换webpack.config.js中entry的入口顺序,那么是否我就不会遇见这个问题了。答案是否定的,除否你能保证资源文件都写在entry的顶部。否则会出现这样的情况:

假如entry的顺序为: app -> common, 那么解析顺序为 index.js → lodash。 如果之后index.js引入了 print.js,那么解析顺序变为 index.js → print.js -> lodash。

以上,我们并没有在entry中更改入口顺序,解析的顺序还是会发生改变,common的hash还是会发生,不能缓存。

这里我们就引入一个新的组件:HashedModuleIdsPlugin:根据hash生成ID(NamedModulesPlugin也具有同样的效果,但是是根据路径名生成ID,可读性更高,也由此编译时间会相对长一些)。 这样module.id就不会使用数字标识符,而使用hash:


const path = require('path');
const webpack = require('webpack');
 
module.exports = {
 entry: {
  common: ['lodash'],
  app: './src/index.js'
 },
 output: {
  filename: '[name].[chunkhash].js',
  path: path.resolve(__dirname, 'dist')
 },
 plugins: [
  new CleanWebpackPlugin(['dist']),
  new webpack.HashedModuleIdsPlugin(), // 引入该插件
  new webpack.optimize.CommonsChunkPlugin({
   name: 'common' // 指代index.js引入的lodash库
  }),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'manifest' // 用于提取manifest
  })
 ]
}

打包发现,之前[ ]里都是数字,现在都是一些字符,

接下来,我们再把app和common的顺序调换一下,并且随意修改index.js,再次打包:

现在大功告成,common的hash没有改变,而因为更变了内容app的hash改变了,这正是我们想要的结果。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn