Dieser Artikel stellt hauptsächlich die Praxis des dauerhaften Caching von Webpacks vor. Jetzt teile ich ihn mit Ihnen und gebe ihn als Referenz.
Vorwort
Vor kurzem habe ich mir angeschaut, wie Webpack persistentes Caching durchführt, und festgestellt, dass es noch einige Fallstricke gibt, die ich danach sortieren und zusammenfassen muss Wenn Sie diesen Artikel lesen, können Sie Folgendes ungefähr verstehen:
Was ist persistentes Caching und warum machen wir persistentes Caching?
Wie funktioniert Webpack persistent? Zwischenspeichern?
Einige Hinweise zum Webpack-Caching.
Persistentes Caching
Zuerst müssen wir erklären, was persistentes Caching ist, im Kontext der aktuellen Beliebtheit von Anwendungen, bei denen Front-End und Unter bestimmten Umständen sind Front-End-HTML, CSS und JS häufig in Form einer statischen Ressourcendatei auf dem Server vorhanden, und Daten werden über Schnittstellen abgerufen, um dynamische Inhalte anzuzeigen. Dabei geht es um die Frage, wie das Unternehmen den Front-End-Code bereitstellt. Es handelt sich also um ein Update-Bereitstellungsproblem. Sollte zuerst die Seite bereitgestellt werden oder zuerst die Ressourcen?
Stellen Sie zuerst die Seite und dann die Ressourcen bereit: Wenn ein Benutzer während des Zeitintervalls zwischen den beiden Bereitstellungen auf die Seite zugreift, wird die alte Ressource in die neue Seitenstruktur geladen und die alte Version der Die Ressource wird als neue Version betrachtet. Wenn die Version zwischengespeichert wird, greift der Benutzer auf eine Seite mit einem ungeordneten Stil zu. Sofern sie nicht manuell aktualisiert wird, bleibt die Seite in einem ungeordneten Zustand, bis der Ressourcencache abläuft.
Zuerst Ressourcen bereitstellen, dann Seiten bereitstellen: Während des Bereitstellungszeitintervalls besuchen Benutzer mit lokal zwischengespeicherten Ressourcen älterer Versionen die Website. Da es sich bei der angeforderten Seite um eine ältere Version handelt, hat sich die Ressourcenreferenz und der Browser nicht geändert Der lokale Cache wird direkt verwendet. Dies ist normal. Wenn jedoch Benutzer ohne lokalen Cache oder abgelaufenem Cache die Website besuchen, lädt die alte Versionsseite die neue Versionsressource, was zu Fehlern bei der Seitenausführung führt.
Deshalb benötigen wir eine Bereitstellungsstrategie, um sicherzustellen, dass Online-Benutzer bei der Aktualisierung unseres Online-Codes reibungslos wechseln und unsere Website korrekt öffnen können.
Es wird empfohlen, zuerst diese Antwort zu lesen: Wie kann man Front-End-Code in einem großen Unternehmen entwickeln und bereitstellen?
Nachdem Sie die obige Antwort gelesen haben, werden Sie ungefähr verstehen, dass die ausgereiftere Lösung für persistentes Caching jetzt darin besteht, einen Hash-Wert nach dem Namen der statischen Ressource hinzuzufügen, da der Hash-Wert bei jeder Änderung der Datei generiert wird Dies hat den Vorteil, dass Dateien inkrementell veröffentlicht werden, um zu vermeiden, dass vorherige Dateien überschrieben werden und der Online-Benutzerzugriff fehlschlägt.
Denn solange die Namen der jedes Mal veröffentlichten statischen Ressourcen (css, js, img) eindeutig sind, kann ich:
Für HTML-Dateien: Tun Aktivieren Sie das Caching nicht, legen Sie den HTML-Code auf Ihrem eigenen Server ab, schalten Sie den Cache des Servers aus. Ihr Server stellt nur HTML-Dateien und Datenschnittstellen bereit.
Für statische JS-, CSS-, Bilder usw. Datei : Aktivieren Sie CDN und Caching und laden Sie statische Ressourcen zum CDN-Dienstanbieter hoch. Da der Pfad jeder Ressource eindeutig ist, wird die Ressource nicht überschrieben, wodurch die Online-Stabilität gewährleistet wird Benutzerzugriff.
Jedes Mal, wenn ein Update veröffentlicht wird, werden zuerst die statischen Ressourcen (js, css, img) an den CDN-Dienst übertragen und dann die HTML-Datei hochgeladen. Dadurch wird sichergestellt, dass alte Benutzer Mit dem normalen Zugriff können neue Benutzer neue Seiten sehen.
Das Obige stellt kurz die gängige Front-End-Lösung für persistentes Caching vor. Warum müssen wir also persistentes Caching durchführen?
Wenn ein Benutzer unsere Website zum ersten Mal mit einem Browser besucht, führt die Seite eine Vielzahl statischer Ressourcen ein. Wenn wir dauerhaftes Caching erreichen können, können wir Cache- im HTTP-Antwort-Header hinzufügen Feld zum Festlegen des Caches, der Browser kann diese Ressourcen einzeln lokal zwischenspeichern.
Wenn der Benutzer bei nachfolgenden Besuchen dieselbe statische Ressource erneut anfordern muss und die statische Ressource nicht abgelaufen ist, kann der Browser direkt den lokalen Cache verwenden, anstatt die Ressource über das Netzwerk anzufordern.
Wie Webpack persistentes Caching durchführt
Nachdem wir das persistente Caching kurz vorgestellt haben, ist das Folgende der entscheidende Punkt. Wie sollten wir also persistentes Caching im Webpack durchführen? Nun, das müssen wir tun Führen Sie die folgenden zwei Dinge aus:
Stellen Sie sicher, dass der Hashwert eindeutig ist, dh für jede verpackte Ressource einen eindeutigen Hashwert generiert Hashwerte sind inkonsistent.
Um die Stabilität des Hash-Werts sicherzustellen, müssen wir sicherstellen, dass sich beim Ändern eines Moduls nur der Hash-Wert der betroffenen gepackten Datei und der Hash-Wert der gepackten Datei ändern Datei, die nichts mit den Moduländerungen zu tun hat.
Hash-Dateiname ist der erste Schritt zur Implementierung von persistentem Caching. Derzeit verfügt Webpack über zwei Möglichkeiten, Hash zu berechnen ([hash] und [chunkhash])
Hash bedeutet, dass jedes Mal, wenn Webpack während des Kompilierungsprozesses einen eindeutigen Hash-Wert generiert, dieser neu erstellt wird, nachdem eine Datei im Projekt geändert wurde, und Webpack dann den neuen Hash-Wert berechnet.
Chunkhash ist ein Hash-Wert, der basierend auf dem Modul berechnet wird, sodass Änderungen an einer bestimmten Datei nur ihren eigenen Hash-Wert und keine anderen Dateien beeinflussen.
Wenn Sie also einfach alles in die gleiche Datei packen, kann Hash Sie zufriedenstellen. Wenn Ihr Projekt das Entpacken, Laden von Modulen usw. umfasst, ist Chunkhash erforderlich, um sicherzustellen, dass nur das Relevante verwendet wird Datei-Hash-Werte ändern sich nach jedem Update.
Unsere Webpack-Konfiguration mit persistentem Cache sollte also so aussehen:
module.exports = { entry: __dirname + '/src/index.js', output: { path: __dirname + '/dist', filename: '[name].[chunkhash:8].js', } }
Die Bedeutung des obigen Codes ist: Verwenden Sie index.js als Einstiegspunkt, um den gesamten Code in eine Datei zu packen heißt index.xxxx.js und wird im dist-Verzeichnis abgelegt. Jetzt können wir jedes Mal, wenn wir das Projekt aktualisieren, eine neu benannte Datei generieren.
Wenn Sie mit einfachen Szenarien zu tun haben, ist dies ausreichend, aber in großen mehrseitigen Anwendungen müssen wir häufig die Leistung der Seite optimieren:
Trennen Geschäftscode und Code von Drittanbietern: Der Grund, warum wir Geschäftscode und Code von Drittanbietern trennen, liegt darin, dass Geschäftscode häufig aktualisiert wird und Aktualisierungen und Iterationen von Code von Drittanbietern langsam sind. Daher trennen wir Code von Drittanbietern (Bibliotheken, Frameworks). Dadurch kann der Cache des Browsers vollständig genutzt werden, um Bibliotheken von Drittanbietern zu laden.
Laden bei Bedarf: Wenn der Benutzer beispielsweise React-Router verwendet und auf eine bestimmte Route zugreifen muss, wird die entsprechende Komponente geladen. Dann muss der Benutzer nicht laden Zu Beginn werden alle Routing-Komponenten lokal heruntergeladen.
In mehrseitigen Anwendungen können wir häufig gemeinsame Module wie Kopfzeile, Fußzeile usw. extrahieren, sodass diese gemeinsamen Module beim Seitenwechsel im Cache vorhanden sind kann es direkt laden, anstatt eine Netzwerkanfrage zu stellen.
Für das Entpacken und Laden in Module ist das integrierte Plug-in des Webpacks erforderlich: CommonsChunkPlugin. Im Folgenden erkläre ich anhand eines Beispiels, wie das Webpack konfiguriert wird.
Der Code dieses Artikels befindet sich auf meinem Github. Wenn Sie interessiert sind, können Sie ihn herunterladen und ansehen:
git clone https://github.com/happylindz/blog.git cd blog/code/multiple-page-webpack-demo npm install
Bevor Sie den folgenden Inhalt lesen, empfehle ich Ihnen dringend, meinen zu lesen Vorheriger Artikel: Ein umfassendes Verständnis des Webpack-Dateipaketierungsmechanismus hilft Ihnen, persistentes Caching besser zu implementieren.
Das Beispiel wird grob so beschrieben: Es besteht aus zwei Seiten, SeiteA und SeiteB
// src/pageA.js import componentA from './common/componentA'; // 使用到 jquery 第三方库,需要抽离,避免业务打包文件过大 import $ from 'jquery'; // 加载 css 文件,一部分为公共样式,一部分为独有样式,需要抽离 import './css/common.css' import './css/pageA.css'; console.log(componentA); console.log($.trim(' do something ')); // src/pageB.js // 页面 A 和 B 都用到了公共模块 componentA,需要抽离,避免重复加载 import componentA from './common/componentA'; import componentB from './common/componentB'; import './css/common.css' import './css/pageB.css'; console.log(componentA); console.log(componentB); // 用到异步加载模块 asyncComponent,需要抽离,加载首屏速度 document.getElementById('xxxxx').addEventListener('click', () => { import( /* webpackChunkName: "async" */ './common/asyncComponent.js').then((async) => { async(); }) }) // 公共模块基本长这样 export default "component X";
Der Inhalt der obigen Seite umfasst im Wesentlichen die drei Arten der Aufteilung unserer Module: Aufteilung der öffentlichen Bibliothek , Laden und Aufteilen gemeinsamer Module nach Bedarf. Dann besteht der nächste Schritt darin, das Webpack zu konfigurieren:
const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: { pageA: [path.resolve(__dirname, './src/pageA.js')], pageB: path.resolve(__dirname, './src/pageB.js'), }, output: { path: path.resolve(__dirname, './dist'), filename: 'js/[name].[chunkhash:8].js', chunkFilename: 'js/[name].[chunkhash:8].js' }, module: { rules: [ { // 用正则去匹配要用该 loader 转换的 CSS 文件 test: /.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader"] }) } ] }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'common', minChunks: 2, }), new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: ({ resource }) => ( resource && resource.indexOf('node_modules') >= 0 && resource.match(/.js$/) ) }), new ExtractTextPlugin({ filename: `css/[name].[chunkhash:8].css`, }), ] }
Das erste CommonsChunkPlugin wird zum Extrahieren öffentlicher Module verwendet, was gleichbedeutend damit ist, Webpack-Chef zu sagen: Wenn Sie sehen, dass ein Modul zweimal oder öfter geladen wird, dann helfen Sie mir bitte beim Umzug Es beträgt hier 2 minChunks und die Granularität ist die kleinste. Sie können auswählen, wie oft Sie die Module verwenden möchten, bevor Sie sie entsprechend Ihrer tatsächlichen Situation extrahieren.
Das zweite CommonsChunkPlugin wird verwendet, um Codes von Drittanbietern zu extrahieren, sie zu extrahieren und festzustellen, ob die Ressourcen von node_modules stammen. Wenn ja, bedeutet dies, dass es sich um Module von Drittanbietern handelt, und extrahieren Sie sie. Dies entspricht der Anweisung an den Webpack-Chef, dass Sie, wenn Sie sehen, dass einige Module aus dem Verzeichnis „node_modules“ stammen und deren Namen mit „.js“ enden, sie bitte in den „Vendor Chunk“ verschieben. Wenn der „Vendor Chunk“ nicht vorhanden ist, erstellen Sie einen neuen.
Was sind die Vorteile dieser Konfiguration? Wenn unser Unternehmen wächst, werden wir wahrscheinlich immer mehr Bibliothekscodes von Drittanbietern verwenden. Wenn wir einen Eingang speziell zum Speichern von Code von Drittanbietern konfigurieren, dann unser Webpack .config.js wird zu:
// 不利于拓展 module.exports = { entry: { app: './src/main.js', vendor: [ 'vue', 'axio', 'vue-router', 'vuex', // more ], }, }
Das dritte ExtractTextPlugin-Plug-in wird verwendet, um CSS aus der gepackten JS-Datei zu extrahieren und eine unabhängige CSS-Datei zu generieren. Stellen Sie sich vor, Sie ändern den Stil nicht Sie möchten auf keinen Fall, dass sich der Hashwert Ihrer JS-Datei ändert. Sie möchten auf jeden Fall, dass CSS und JS voneinander getrennt sind und sich nicht gegenseitig beeinflussen.
Nachdem Sie Webpack ausgeführt haben, können Sie den Effekt der Verpackung sehen:
├── css │ ├── common.2beb7387.css │ ├── pageA.d178426d.css │ └── pageB.33931188.css └── js ├── async.03f28faf.js ├── common.2beb7387.js ├── pageA.d178426d.js ├── pageB.33931188.js └── vendor.22a1d956.js
Sie können sehen, dass CSS und JS getrennt wurden und wir das Modul aufgeteilt haben, um die Einzigartigkeit des Modulblocks sicherzustellen . Jedes Mal, wenn Sie den Code aktualisieren, wird ein anderer Hashwert generiert.
Bei der Einzigartigkeit müssen wir die Stabilität des Hash-Werts sicherstellen. Stellen Sie sich dieses Szenario vor. Sie möchten auf keinen Fall, dass Ihre Änderung eines bestimmten Teils des Codes (Modul, CSS) den Hash-Wert verursacht Wenn sich die Datei vollständig ändert, ist das offensichtlich unklug. Was sollten wir also tun, um die Änderung des Hash-Werts zu minimieren?
Mit anderen Worten, wir müssen die Faktoren herausfinden, die Cache-Fehler bei der Webpack-Kompilierung verursachen, und Wege finden, diese zu lösen oder zu optimieren?
Die Änderung des Chunkhash-Werts wird hauptsächlich durch die folgenden vier Teile verursacht:
Der Quellcode, der das Modul enthält
verwendetes Webpack Der Laufzeitcode, der ausgeführt wird
Die vom Webpack generierte Modulmodul-ID (einschließlich der Modul-ID und der referenzierten abhängigen Modul-ID)
chunkID
Solange sich ein Teil dieser vier Teile ändert, ist die generierte Chunk-Datei unterschiedlich und der Cache wird ungültig. Im Folgenden werden die vier Teile nacheinander vorgestellt:
1. Änderungen am Quellcode:
显然不用多说,缓存必须要刷新,不然就有问题了
二、webpack 启动运行的 runtime 代码:
看过我之前的文章:深入理解 webpack 文件打包机制 就会知道,在 webpack 启动的时候需要执行一些启动代码。
(function(modules) { window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { // ... }; function __webpack_require__(moduleId) { // ... } __webpack_require__.e = function requireEnsure(chunkId, callback) { // ... script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"pageA","1":"pageB","3":"vendor"}[chunkId]||chunkId) + "." + {"0":"e72ce7d4","1":"69f6bbe3","2":"9adbbaa0","3":"53fa02a7"}[chunkId] + ".js"; }; })([]);
大致内容像上面这样,它们是 webpack 的一些启动代码,它们是一些函数,告诉浏览器如何加载 webpack 定义的模块。
其中有一行代码每次更新都会改变的,因为启动代码需要清楚地知道 chunkid 和 chunkhash 值得对应关系,这样在异步加载的时候才能正确地拼接出异步 js 文件的路径。
那么这部分代码最终放在哪个文件呢?因为我们刚才配置的时候最后生成的 common chunk 模块,那么这部分运行时代码会被直接内置在里面,这就导致了,我们每次更新我们业务代码(pageA, pageB, 模块)的时候, common chunkhash 会一直变化,但是这显然不符合我们的设想,因为我们只是要用 common chunk 用来存放公共模块(这里指的是 componentA),那么我 componentA 都没去修改,凭啥 chunkhash 需要变了。
所以我们需要将这部分 runtime 代码抽离成单独文件。
module.exports = { // ... plugins: [ // ... // 放到其他的 CommonsChunkPlugin 后面 new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', minChunks: Infinity, }), ] }
这相当于是告诉 webpack 帮我把运行时代码抽离,放到单独的文件中。
├── css │ ├── common.4cc08e4d.css │ ├── pageA.d178426d.css │ └── pageB.33931188.css └── js ├── async.03f28faf.js ├── common.4cc08e4d.js ├── pageA.d178426d.js ├── pageB.33931188.js ├── runtime.8c79fdcd.js └── vendor.cef44292.js
多生成了一个 runtime.xxxx.js,以后你在改动业务代码的时候,common chunk 的 hash 值就不会变了,取而代之的是 runtime chunk hash 值会变,既然这部分代码是动态的,可以通过 chunk-manifest-webpack-plugin 将他们 inline 到 html 中,减少一次网络请求。
三、webpack 生成的模块 moduleid
在 webpack2 中默认加载 OccurrenceOrderPlugin 这个插件,OccurrenceOrderPlugin 插件会按引入次数最多的模块进行排序,引入次数的模块的 moduleId 越小,但是这仍然是不稳定的,随着你代码量的增加,虽然代码引用次数的模块 moduleId 越小,越不容易变化,但是难免还是不确定的。
默认情况下,模块的 id 是这个模块在模块数组中的索引。OccurenceOrderPlugin 会将引用次数多的模块放在前面,在每次编译时模块的顺序都是一致的,如果你修改代码时新增或删除了一些模块,这将可能会影响到所有模块的 id。
最佳实践方案是通过 HashedModuleIdsPlugin 这个插件,这个插件会根据模块的相对路径生成一个长度只有四位的字符串作为模块的 id,既隐藏了模块的路径信息,又减少了模块 id 的长度。
这样一来,改变 moduleId 的方式就只有文件路径的改变了,只要你的文件路径值不变,生成四位的字符串就不变,hash 值也不变。增加或删除业务代码模块不会对 moduleid 产生任何影响。
module.exports = { plugins: [ new webpack.HashedModuleIdsPlugin(), // 放在最前面 // ... ] }
四、chunkID
实际情况中分块的个数的顺序在多次编译之间大多都是固定的, 不太容易发生变化。
这里涉及的只是比较基础的模块拆分,还有一些其它情况没有考虑到,比如异步加载组件中包含公共模块,可以再次将公共模块进行抽离。形成异步公共 chunk 模块。有想深入学习的可以看这篇文章:Webpack 大法之 Code Splitting
webpack 做缓存的一些注意点
CSS 文件 hash 值失效的问题
不建议线上发布使用 DllPlugin 插件
CSS 文件 hash 值失效的问题:
ExtractTextPlugin 有个比较严重的问题,那就是它生成文件名所用的[chunkhash]是直接取自于引用该 css 代码段的 js chunk ;换句话说,如果我只是修改 css 代码段,而不动 js 代码,那么最后生成出来的 css 文件名依然没有变化。
所以我们需要将 ExtractTextPlugin 中的 chunkhash 改为 contenthash,顾名思义,contenthash 代表的是文本文件内容的 hash 值,也就是只有 style 文件的 hash 值。这样编译出来的 js 和 css 文件就有独立的 hash 值了。
module.exports = { plugins: [ // ... new ExtractTextPlugin({ filename: `css/[name].[contenthash:8].css`, }), ] }
如果你使用的是 webpack2,webpack3,那么恭喜你,这样就足够了,js 文件和 css 文件修改都不会影响到相互的 hash 值。那如果你使用的是 webpack1,那么就会出现问题。
具体来讲就是 webpack1 和 webpack 在计算 chunkhash 值得不同:
webpack1 在涉及的时候并没有考虑像 ExtractTextPlugin 会将模块内容抽离的问题,所以它在计算 chunkhash 的时候是通过打包之前模块内容去计算的,也就是说在计算的时候 css 内容也包含在内,之后才将 css 内容抽离成单独的文件,
那么就会出现:如果只修改了 css 文件,未修改引用的 js 文件,那么编译输出的 js 文件的 hash 值也会改变。
In dieser Hinsicht hat webpack2 Verbesserungen vorgenommen. Es berechnet den Hash-Wert basierend auf dem Inhalt der gepackten Datei, sodass es nach dem Extrahieren des CSS-Codes durch ExtractTextPlugin kein Problem wie oben gibt. Wenn Sie leider immer noch webpack1 verwenden, wird empfohlen, das Plug-in md5-hash-webpack-plugin zu verwenden, um die Webpack-Hash-Berechnungsstrategie zu ändern.
Es wird nicht empfohlen, das DllPlugin-Plug-in für die Online-Veröffentlichung zu verwenden
Warum sagen Sie das? Denn kürzlich kam ein Freund zu mir und fragte mich, warum sein Leiter die Online-Nutzung des DllPlugin-Plugins nicht zulässt.
DllPlugin selbst weist mehrere Mängel auf:
Zunächst müssen Sie eine zusätzliche Webpack-Konfiguration konfigurieren, was den Arbeitsaufwand erhöht.
Eine der Seiten verwendet eine große Abhängigkeitsbibliothek eines Drittanbieters und andere Seiten müssen sie überhaupt nicht verwenden, aber es lohnt sich nicht, sie direkt in dll.js zu packen Dieser nutzlose Code muss bei jedem Öffnen der Seite geladen werden und die Code-Splitting-Funktion von webpack2 kann nicht verwendet werden.
Sie müssen die DLL-Datei herunterladen, wenn Sie sie zum ersten Mal öffnen. Da Sie viele Bibliotheken gebündelt haben, ist die DLL-Datei sehr groß und die Seitenladegeschwindigkeit beim ersten Mal Die Zeit ist sehr langsam.
Obwohl Sie es in eine DLL-Datei packen und den Browser den Cache lesen lassen können, sodass Sie ihn beim nächsten Mal nicht anfordern müssen, wenn Sie beispielsweise eine davon verwenden Die lodash-Funktion und Sie verwenden dll Die gesamte lodash-Datei wird importiert, was dazu führt, dass Sie zu viel nutzlosen Code laden, was der Renderzeit des ersten Bildschirms nicht zuträglich ist.
Ich denke, der richtige Ansatz ist:
Bibliotheken mit starker Integrität wie React und Vue können Bibliotheken von Drittanbietern generieren, um Caching durchzuführen. Da Ihr allgemeines technisches System fest ist und grundsätzlich ein einheitliches technisches System auf einer Site verwendet wird, wird eine Anbieterbibliothek zum Zwischenspeichern generiert.
Funktionale Komponentenbibliotheken wie antd und lodash können durch Tree-Shaking entfernt werden, so dass nur nützlicher Code übrig bleibt. Fügen Sie ihn niemals direkt in die Bibliothek des Drittanbieters ein, da er sonst ausgeführt wird viel nutzloser Code.
Fazit
Okay, ich habe das Gefühl, dass ich durch das Lesen von Webpack in letzter Zeit wirklich viel gewonnen habe. Ich hoffe, dass Sie aus dem Artikel auch etwas lernen können. Darüber hinaus empfehle ich noch einmal den Artikel, den ich zuvor geschrieben habe, der Ihnen helfen kann, den Datei-Caching-Mechanismus besser zu verstehen: Detailliertes Verständnis des Webpack-Dateiverpackungsmechanismus
Das Obige ist, was ich hoffentlich für alle zusammengestellt habe Es wird in Zukunft für alle hilfreich sein.
Verwandte Artikel:
Ein sehr praktisches Ajax-Benutzerregistrierungsmodul
Ajax-Klick zum kontinuierlichen Laden der Datenliste (grafisches Tutorial)
Ajax+Struts2 implementiert die Verifizierungscode-Verifizierungsfunktion (grafisches Tutorial)
Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über die Praxis des dauerhaften Cachings von Webpack. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!