Heim > Web-Frontend > js-Tutorial > Über die Verwendung von Webpack-Caching und unabhängiger Verpackung

Über die Verwendung von Webpack-Caching und unabhängiger Verpackung

巴扎黑
Freigeben: 2017-08-06 15:07:03
Original
1200 Leute haben es durchsucht

Dieser Artikel stellt hauptsächlich die erweiterte Verwendung von Webpack vor – Caching und unabhängige Verpackung. Der Herausgeber findet ihn recht gut, daher werde ich ihn jetzt mit Ihnen teilen und als Referenz verwenden. Lassen Sie uns dem Herausgeber folgen und einen Blick darauf werfen.

Dieser Artikel stellt die Verwendung von Caching und unabhängiger Verpackung vor. Ich hoffe, er wird für alle hilfreich sein

Werfen wir zunächst einen Blick auf die Grundlagen der Webpack-Konfiguration:


var path = require('path');
 
module.exports = {
 entry: './src/index.js',
 output: {
  filename: 'bundle.js',
  path: path.resolve(__dirname, 'dist')
 }
}
Nach dem Login kopieren
Einführung der Lodash-Bibliothek in 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());
Nach dem Login kopieren
Nach dem Packen wird nur ein bundle.js generiert. In diesem Fall wird jedes Mal, wenn Sie eine Ressourcendatei laden möchten, Der Browser lädt die Lodash-Bibliothek, die sich überhaupt nicht ändert, also sehr ineffizient.


Da der Browser bei jedem Besuch des Browsers die Ressourcen erneut herunterlädt, kann es sein, dass das Netzwerk langsam ist, um Ressourcen abzurufen, und dass die Seite möglicherweise längere Zeit nicht geladen wird, was ineffizient ist unfreundlich, sodass der Browser Ressourcen zwischenspeichert, um sie nicht jedes Mal über das Netzwerk abrufen zu müssen, wenn Sie darauf zugreifen.


Aufgrund des Browser-Caching treten jedoch neue Probleme auf. Wenn wir den Dateinamen der Ressource bei der Bereitstellung der Version nicht ändern, geht der Browser möglicherweise davon aus, dass er nicht aktualisiert wurde und verwendet wird seine zwischengespeicherte Version.


Auf diese Weise müssen wir zwei Probleme lösen:

Zuerst müssen wir die gepackten Dateien trennen. Zweitens lösen Sie das Caching-Problem.


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库
  })
 ]
}
Nach dem Login kopieren
Hauptänderungen:

  • Plug-in hinzufügen: CommonsChunkPlugin, importierte Bibliothek extrahieren, umbenennen und Implementierung der Codetrennung.

  • Dem Namen in der Ausgabe wird ein Hash hinzugefügt. Nach jedem Paket ist der Hash-Wert unterschiedlich, wodurch das Problem des Browser-Caching gelöst wird.

Ergebnis: index.js wird als app.[hash].js gepackt, und der von index.js eingeführte lodash wird als common.[hash].js gepackt. Dadurch wird das Browser-Cache-Problem gelöst und die Trennung von statischem Ressourcencode und Quellcode erreicht, es treten jedoch erneut neue Probleme auf.

Nach dem ersten Paket (beachten Sie den Namen unter der Asset-Spalte):

Jedes Mal, wenn wir den Quellcode ändern, verpacken Sie ihn erneut und nicht nur indizieren generation Der Hashwert von app.[hash].js hat sich geändert,

und der Hashwert von common.[hash].js ist derselbe wie der Hashwert von app und hat sich auch geändert (Sie können es selbst testen, es zuerst einmal mit Webpack packen, index.js ändern und es erneut packen).

Dies ist nicht das gewünschte Ergebnis. Obwohl die Quellcode-Hash-Änderung das Problem löst, dass der Browser die zwischengespeicherte Version verwendet, ändert sich auch der Browser, wenn sich der Hash-Wert von common.js ändert Fordern Sie den allgemeinen statischen Code an, der sich nicht jedes Mal ändert, was immer noch Netzwerkressourcen verschwendet und sehr ineffizient ist.

Hinweis: In diesem Fall werden mehrere Junk-Dateien im dist-Verzeichnis generiert. Bei der tatsächlichen Verwendung wird das CleanWebpackPlugin-Plugin verwendet.


Code kopieren Der Code lautet wie folgt:

new CleanWebpackPlugin(['dist']) // Für jedes zum Plugin-Array hinzufügen Vor dem Verpacken sollten alle zuvor verpackten Dateien im Verpackungsordner gelöscht werden.

Wenn der Index geändert wird, ändert sich nur der Hash-Wert der generierten App, der Hash-Wert der gemeinsamen App ändert sich jedoch nicht. Dann kann unser Ziel erreicht werden, indem sowohl die Bibliothek zwischengespeichert als auch gespeichert wird und identifizieren Sie die Quelle der Dateiänderungen.

Wir konfigurieren wie folgt: Ändern Sie [name].[hash].js in der Ausgabe in [name].[chunkhash].js, sodass jede Datei einen eindeutigen Hash-Wert generiert:


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库
  })
 ]
}
Nach dem Login kopieren
(Hinweis: Verwenden Sie [chunkhash] nicht in der Entwicklungsumgebung, da dies die Kompilierungszeit verlängert. Trennen Sie die Konfiguration für den Entwicklungs- und Produktionsmodus und verwenden Sie [name].js im Entwicklungsmodus. Der Dateiname lautet [ name].[chunkhash].js im Produktionsmodus, wenn also das HotModuleReplacementPlugin zu diesem Zeitpunkt verwendet wird, schlägt die Kompilierung fehl)


Wir führen nach der Konfiguration die Webpack-Verpackung durch:

Chunkhash ist ein Hash, der basierend auf dem Dateiinhalt generiert wird. Es ist ersichtlich, dass die von der App und Common generierten Hash-Werte unterschiedlich sind (verwenden Sie [Name] zum Vergleich. [Hash]). js-Paket).


Wir nehmen zufällige Änderungen in index.js vor und verpacken es erneut:

Das Seltsame ist, dass Common und App zwar separate Hashwerte generieren , aber nach dem Ändern von index.js ändert sich der Hashwert von common immer noch.

原因是:为了最小化生成的文件大小,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
  })
 ]
}
Nach dem Login kopieren

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
  })
 ]
}
Nach dem Login kopieren

打包后:

这里发现对比上一张图片发现,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
  })
 ]
}
Nach dem Login kopieren

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

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

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

Das obige ist der detaillierte Inhalt vonÜber die Verwendung von Webpack-Caching und unabhängiger Verpackung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage