Beschleunigung der Erstellung von Webanwendungen mit Webpack

Während sich Ihre Anwendung entwickelt und wächst, erhöht sich auch ihre Erstellungszeit - von einigen Minuten während des Zusammenbaus im Entwicklungsmodus bis zu zehn Minuten während der „kalten“ Produktionsmontage. Dies ist völlig inakzeptabel. Wir Entwickler möchten nicht den Kontext wechseln, während wir darauf warten, dass das Bundle fertig ist, und möchten so früh wie möglich Feedback von der Anwendung erhalten - idealerweise beim Wechsel von der IDE zum Browser.


Wie erreicht man das? Was können wir tun, um die Erstellungszeit zu optimieren?


Dieser Artikel bietet einen Überblick über vorhandene Tools im Webpack-Ökosystem, um die Montage, ihre Erfahrungen und Tipps zu beschleunigen.


Die Optimierung der Bundle-Größe und Leistung der Anwendung selbst wird in diesem Artikel nicht berücksichtigt.


Das Projekt, auf das im Text verwiesen wird und in Bezug auf das Messungen der Montagegeschwindigkeit durchgeführt werden, ist eine relativ kleine Anwendung, die mit Webpack, Babel, PostCSS, Sass usw. auf den Stapel JS + Flow + React + Redux geschrieben wurde und aus etwa 30.000 besteht Codezeilen und 1.500 Module. Abhängigkeitsversionen sind ab April 2019 aktuell.


Die Studien wurden auf einem Computer mit Windows 10, Node.js 8, einem 4-Core-Prozessor, 8 GB Speicher und SSD durchgeführt.


Terminologie


  • Beim Zusammenstellen werden Projektquelldateien in eine Reihe verwandter Assets konvertiert, die zusammen eine Webanwendung bilden.
  • dev-mode - Assembly mit dem Optionsmodus mode: 'development' , normalerweise mit webpack-dev-server und watch-mode.
  • Prod-Modus - Assembly mit dem Optionsmodus mode: 'production' , normalerweise mit einem vollständigen Satz von Bundle-Optimierungen.
  • Inkrementelle Erstellung - im Dev-Modus: Nur Dateien mit Änderungen neu erstellen.
  • "Cold" Build - Build von Grund auf neu, ohne Caches, aber mit installierten Abhängigkeiten.

Caching


Mit Caching können Sie die Ergebnisse von Berechnungen zur weiteren Wiederverwendung speichern. Die erste Assembly kann aufgrund des Caching-Overheads etwas langsamer als gewöhnlich sein, die nachfolgenden werden jedoch aufgrund der Wiederverwendung der Ergebnisse der Kompilierung unveränderter Module viel schneller sein.


Standardmäßig speichert Webpack im Überwachungsmodus Zwischenerstellungsergebnisse im Arbeitsspeicher zwischen, um nicht bei jeder Änderung das gesamte Projekt neu zusammenzusetzen. Für einen normalen Build (nicht im Überwachungsmodus) ist diese Einstellung nicht sinnvoll. Sie können auch versuchen, die Cache-Auflösung zu aktivieren, um die Webpack-Suche nach Modulen zu vereinfachen und festzustellen, ob sich diese Einstellung spürbar auf Ihr Projekt auswirkt.


Es gibt keinen dauerhaften (auf Festplatte oder anderem Speicher gespeicherten) Cache im Webpack, obwohl versprochen wird, ihn in Version 5 hinzuzufügen . In der Zwischenzeit können wir folgende Tools verwenden:


- Zwischenspeichern in den TerserWebpackPlugin-Einstellungen


Standardmäßig deaktiviert. Auch alleine wirkt es sich spürbar positiv aus: 60,7 s → 39 s (-36%), passt gut zu anderen Caching-Tools.


Das Ein- und Ausschalten ist sehr einfach:


 optimization: { minimizer: [ new TerserJsPlugin({ terserOptions: { ... }, cache: true }) ] } 

- Cache-Loader


Der Cache-Loader kann in eine beliebige Loader-Kette eingefügt werden und die Ergebnisse früherer Loader zwischenspeichern.


Standardmäßig wird der Cache im Ordner .cache-loader im Projektstamm gespeichert. Mit der Option cacheDirectory in den Loader-Einstellungen kann der Pfad neu definiert werden.


Anwendungsbeispiel:


 { test: /\.js$/, use: [ { loader: 'cache-loader', options: { cacheDirectory: path.resolve( __dirname, 'node_modules/.cache/cache-loader' ), }, }, 'babel-loader' ] } 

Sichere und zuverlässige Lösung. Es funktioniert problemlos mit fast jedem Loader: für Skripte (babel-loader, ts-loader), Stile (scss-, less-, postcss-, css-loader), Bilder und Schriftarten (image-webpack-loader, react-svg- Loader, File-Loader) usw.


Beachten Sie:


  • Wenn Sie den Cache-Loader in Verbindung mit dem Style-Loader oder MiniCssExtractPlugin.loader verwenden, sollte er nach ihnen platziert werden:
    ['style-loader', 'cache-loader', 'css-loader', ...] .
  • Im Gegensatz zu den Empfehlungen der Dokumentation, diesen Lader zum Zwischenspeichern der Ergebnisse nur mühsamer Berechnungen zu verwenden, kann dies für die „leichteren“ Lader eine kleine, aber messbare Leistungssteigerung bedeuten - Sie müssen versuchen, zu messen.

Ergebnisse:


  • dev: 35,5 s → (Cache-Loader aktivieren) → 36,2 s (+ 2%) → (Zusammenbau) → 7,9 s (-78%)
  • Produkt: 60,6 s → (Cache-Loader aktivieren) → 61,5 s (+ 1,5%) → (Zusammenbau) → 30,6 s (-49%) → (Cache für Terser einschalten) → 15, 4 s (-75%)

- HardSourceWebpackPlugin


Eine massivere und „intelligentere“ Lösung für das Caching auf der Ebene des gesamten Montageprozesses anstelle einzelner Laderketten. Im grundlegenden Anwendungsfall reicht es aus, das Plugin zur Webpack-Konfiguration hinzuzufügen. Die Standardeinstellungen sollten für den korrekten Betrieb ausreichen. Geeignet für diejenigen, die maximale Leistung erzielen möchten und keine Angst vor Schwierigkeiten haben.


 plugins: [ ..., new HardSourceWebpackPlugin() ] 

Die Dokumentation enthält Anwendungsbeispiele mit erweiterten Einstellungen und Tipps zur Lösung möglicher Probleme. Bevor das Plug-In fortlaufend in Betrieb genommen wird, sollte der Betrieb in verschiedenen Situationen und Montagemodi gründlich getestet werden.


Ergebnisse:


  • dev: 35,5 s → (Plugin aktivieren) → 36,5 s (+ 3%) → (Zusammenbau) → 3,7 s (-90%)
  • Produkt: 60,6 s → (Plugin einschalten) → 69,5 s (+ 15%) → (Zusammenbau) → 25 s (-59%) → (Cache für Terser einschalten) → 10 s (-83%)

Vorteile:


  • Im Vergleich zum Cache-Loader beschleunigt es den Zusammenbau noch mehr.
  • Es sind keine doppelten Deklarationen an verschiedenen Stellen der Konfiguration erforderlich, wie im Cache-Loader.

Nachteile:


  • Im Vergleich zum Cache-Loader verlangsamt es den ersten Build mehr (wenn kein Festplatten-Cache vorhanden ist).
  • kann die inkrementelle Wiederherstellungszeit geringfügig verlängern;
  • kann Probleme bei der Verwendung von webpack-dev-server verursachen und eine detaillierte Konfiguration der Cache-Trennung und -Invalidierung erfordern (siehe Dokumentation );
  • einige Probleme mit Fehlern auf GitHub.

- Caching in Babel-Loader-Einstellungen . Standardmäßig deaktiviert. Der Effekt ist um einige Prozent schlechter als beim Cache-Loader.


- Caching in Eslint-Loader-Einstellungen . Standardmäßig deaktiviert. Wenn Sie diesen Loader verwenden, hilft Ihnen der Cache dabei, beim Zusammensetzen keine Zeit mit unveränderten Dateien zu verschwenden.




Wenn Sie Cache-Loader oder HardSourceWebpackPlugin verwenden, müssen Sie die integrierten Caching-Mechanismen in anderen Plugins oder Loadern deaktivieren (mit Ausnahme von TerserWebpackPlugin), da diese in wiederholten und inkrementellen Builds nicht mehr nützlich sind und "kalte" sogar langsamer werden. Gleiches gilt für den Cache-Loader selbst, wenn HardSourceWebpackPlugin bereits verwendet wird.




Beim Einrichten des Caching können folgende Fragen auftreten:


Wo sollen die Caching-Ergebnisse gespeichert werden?


node_modules/.cache/<_>/ werden normalerweise im node_modules/.cache/<_>/ gespeichert. Die meisten Tools verwenden diesen Pfad standardmäßig und ermöglichen es Ihnen, ihn zu überschreiben, wenn Sie den Cache an einer anderen Stelle speichern möchten.


Wann und wie wird der Cache ungültig?


Es ist sehr wichtig, den Cache zu leeren, wenn Änderungen an der Build-Konfiguration vorgenommen werden, die sich auf die Ausgabe auswirken. Die Verwendung des alten Caches ist in solchen Fällen schädlich und kann zu Fehlern unbekannter Art führen.


Zu berücksichtigende Faktoren:


  • Liste der Abhängigkeiten und ihrer Versionen: package.json, package-lock.json, yarn.lock, .yarn-Integrität;
  • Inhalte von Webpack, Babel, PostCSS, Browserliste und anderen Konfigurationsdateien, die explizit oder implizit von Loadern und Plugins verwendet werden.

Wenn Sie keinen Cache-Loader oder HardSourceWebpackPlugin verwenden, mit dem Sie die Liste der Quellen neu definieren können, um den Assembly-Fingerabdruck zu erstellen, helfen Ihnen npm-Skripte, die den Cache beim Hinzufügen, Aktualisieren oder Entfernen von Abhängigkeiten leeren:


 "prunecaches": "rimraf ./node_modules/.cache/", "postinstall": "npm run prunecaches", "postuninstall": "npm run prunecaches" 

Nodemon, der so konfiguriert ist, dass der Cache geleert und der Webpack-Dev-Server neu gestartet wird, wenn Änderungen in Konfigurationsdateien festgestellt werden, hilft auch:


 "start": "cross-env NODE_ENV=development nodemon --exec \"webpack-dev-server --config webpack.config.dev.js\"" 

nodemon.json


 { "watch": [ "webpack.config.dev.js", "babel.config.js", "more configs...", ], "events": { "restart": "yarn prunecaches" } } 

Muss ich den Cache im Projekt-Repository speichern?


Da es sich bei dem Cache tatsächlich um ein Assembly-Artefakt handelt, muss es nicht in das Repository übernommen werden. Der Speicherort des Caches im Ordner node_modules, der in der Regel in .gitignore enthalten ist, hilft dabei.


Es ist anzumerken, dass wenn es ein Caching-System gäbe, das die Gültigkeit des Caches unter allen Bedingungen, einschließlich der Änderung des Betriebssystems und der Version von Node.js, zuverlässig bestimmen könnte, der Cache zwischen Entwicklungsmaschinen oder in CI wiederverwendet werden könnte, was die Zeit bereits beim ersten Build drastisch verkürzen würde zwischen Zweigen wechseln.


In welchen Build-Modi lohnt es sich und in welchen lohnt es sich nicht, einen Cache zu verwenden?


Hier gibt es keine eindeutige Antwort: Es hängt alles davon ab, wie intensiv Sie während der Entwicklung Dev- und Prod-Modi verwenden und zwischen ihnen wechseln. Im Allgemeinen verhindert nichts das Aktivieren des Cachings überall, aber denken Sie daran, dass es normalerweise den ersten Build verlangsamt. In CI benötigen Sie wahrscheinlich immer einen "sauberen" Build. In diesem Fall kann das Caching mithilfe der entsprechenden Umgebungsvariablen deaktiviert werden.




Interessante Materialien zum Caching im Webpack:



Parallelisierung


Durch die Parallelisierung können Sie die Leistung steigern, indem Sie alle verfügbaren Prozessorkerne verwenden. Der Endeffekt ist für jedes Auto individuell.


Übrigens, hier ist ein einfacher Node.js-Code, um die Anzahl der verfügbaren Prozessorkerne abzurufen (dies kann nützlich sein, wenn Sie die unten aufgeführten Tools einrichten):


 const os = require('os'); const cores = os.cpus().length; 

- Parallelisierung in den TerserWebpackPlugin-Einstellungen


Standardmäßig deaktiviert. Neben dem eigenen Caching lässt es sich leicht einschalten und beschleunigt die Baugruppe spürbar.


 optimization: { minimizer: [ new TerserJsPlugin({ terserOptions: { ... }, parallel: true }) ] } 

- Fadenlader


Thread-Loader können in eine Kette von Loadern eingefügt werden, die umfangreiche Berechnungen durchführen. Danach verwenden frühere Loader den Unterprozesspool Node.js (Prozessoren).


Es gibt eine Reihe von Optionen, mit denen Sie die Arbeit des Pools von Arbeitnehmern optimieren können, obwohl die Grundwerte völlig angemessen aussehen. poolTimeout und workers verdienen besondere Aufmerksamkeit - siehe ein Beispiel .


Es kann zusammen mit dem Cache-Loader wie folgt verwendet werden (Reihenfolge ist wichtig): ['cache-loader', 'thread-loader', 'babel-loader'] . Wenn das Aufwärmen für Thread-Loader aktiviert ist, sollten Sie die Stabilität wiederholter Assemblys, die den Cache verwenden, überprüfen. Das Webpack kann hängen bleiben und den Vorgang nicht abschließen, nachdem die Assembly erfolgreich abgeschlossen wurde. In diesem Fall schalten Sie einfach das Aufwärmen aus.


Wenn nach dem Hinzufügen eines Thread-Loaders zur Sass-Kompilierungskette ein Build-Hang auftritt, kann dieser Tipp hilfreich sein.


- Happypack


Ein Plugin, das Aufrufe von Loadern abfängt und deren Arbeit auf mehrere Threads verteilt. Derzeit befindet es sich im Support-Modus (dh die Entwicklung ist nicht geplant), und der Ersteller empfiehlt den Thread-Loader als Ersatz. Wenn Ihr Projekt auf dem neuesten Stand ist, ist es daher besser, auf HappyPack zu verzichten, obwohl es sich auf jeden Fall lohnt, die Ergebnisse mit dem Thread-Loader zu vergleichen.


HappyPack verfügt über eine verständliche Konfigurationsdokumentation, die an sich eher ungewöhnlich ist: Es wird vorgeschlagen, die Loader-Konfigurationen in den Plug-In-Konstruktoraufruf zu verschieben und die Loader-Ketten selbst durch einen eigenen Happypack-Loader zu ersetzen. Ein solcher nicht standardmäßiger Ansatz kann zu Unannehmlichkeiten beim Erstellen einer benutzerdefinierten Webpack-Konfiguration "aus Teilen" führen.


HappyPack unterstützt eine begrenzte Liste von Ladern . Die wichtigsten und am häufigsten verwendeten in dieser Liste sind vorhanden, aber die Leistung anderer ist aufgrund möglicher Inkompatibilität der API nicht garantiert. Weitere Informationen finden Sie in den Ausgaben des Projekts.


Ablehnung von Berechnungen


Jede Arbeit braucht Zeit. Um weniger Zeit zu verbringen, müssen Sie Arbeiten vermeiden, die wenig nützlich sind, möglicherweise auf später verschoben werden oder in dieser Situation überhaupt nicht benötigt werden.


- Wenden Sie Lader auf so wenige Module wie möglich an


Die Eigenschaften test, exclude und include geben die Bedingungen für die Einbeziehung des Moduls in den Verarbeitungsprozess durch den Loader an. Es geht darum, die Transformation von Modulen zu vermeiden, die diese Transformation nicht benötigen.


Ein beliebtes Beispiel ist die Ausnahme von node_modules von der Transpilation über Babel:


 rules: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader' } ] 

Ein weiteres Beispiel ist, dass normale CSS-Dateien nicht von einem Präprozessor verarbeitet werden müssen:


 rules: [ { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] 

- Aktivieren Sie keine Optimierungen der Bundle-Größe im Dev-Modus


Auf einem leistungsstarken Entwicklercomputer mit stabilem Internet wird eine lokal bereitgestellte Anwendung normalerweise schnell gestartet, selbst wenn sie einige Megabyte wiegt. Die Optimierung eines Bündels während der Montage kann viel mehr Zeit in Anspruch nehmen als die Einsparung von Last.


Der Rat betrifft JS (Terser, Uglify usw. ), CSS (cssnano, Optimize-CSS-Assets-Webpack-Plugin), SVG und Bilder (SVGO, Imagemin, Image-Webpack-Loader), HTML (HTML-Minifier, Option in HTML-Webpack-Plugin) usw.


- Schließen Sie keine Polyfills und Transformationen in den Dev-Modus ein


Wenn Sie babel-preset-env, postcss-preset-env oder Autoprefixer verwenden, fügen Sie eine separate Browserlistenkonfiguration für den Dev-Modus hinzu, die nur die Browser enthält, die Sie während der Entwicklung verwenden. Höchstwahrscheinlich handelt es sich hierbei um die neuesten Versionen von Chrome oder Firefox, die moderne Standards ohne Polyfills und Transformationen perfekt unterstützen. Dadurch wird unnötige Arbeit vermieden.


Beispiel .browserslistrc:


 [production] your supported browsers go here... [development] last 2 Chrome versions last 2 Firefox versions last 1 Safari version 

- Überprüfen Sie die Verwendung von Quellkarten


Das Generieren der genauesten und vollständigsten devtool: 'source-map' nimmt viel Zeit in devtool: 'source-map' (bei unserem Projekt - etwa 30% der devtool: 'source-map' mit der devtool: 'source-map' ). Überlegen Sie, ob Sie Quellkarten in der Produktbaugruppe benötigen (lokal und in CI). Es kann sich lohnen, sie nur bei Bedarf zu generieren - beispielsweise basierend auf einer Umgebungsvariablen oder einem Tag auf dem Commit.


Im Dev-Modus gibt es in den meisten Fällen eine eher leichte Option - 'cheap-eval-source-map' oder 'cheap-module-eval-source-map' . Weitere Informationen finden Sie in der Webpack- Dokumentation .


- Richten Sie die Komprimierung in Terser ein


Laut der Terser-Dokumentation (dasselbe gilt für Uglify) wird beim Minimieren des Codes der überwiegende Teil der Zeit von den mangle und compress Optionen verbraucht. Durch die Feinabstimmung können Sie eine Montagebeschleunigung auf Kosten einer geringfügigen Vergrößerung der Bündelgröße erzielen. Es gibt ein Beispiel in den Quellen von vue-cli und ein weiteres Beispiel eines Ingenieurs von Slack. In unserem Projekt reduziert die Terser-Abstimmung in der ersten Ausführungsform die Montagezeit um etwa 7% im Austausch für eine 2,5-prozentige Erhöhung der Bündelgröße. Ob das Spiel die Kerze wert ist, liegt bei Ihnen.


- Schließen Sie externe Abhängigkeiten vom Parsen aus


Mit den resolve.alias module.noParse und resolve.alias Sie den Import von Bibliotheksmodulen auf bereits kompilierte Versionen umleiten und diese einfach in das Bundle einfügen, ohne Zeit mit dem Parsen zu verschwenden. Im Dev-Modus sollte dies die Montagegeschwindigkeit erheblich erhöhen, auch inkrementell.


Der Algorithmus ist ungefähr der folgende:


(1) Erstellen Sie eine Liste der Module, die beim Parsen übersprungen werden müssen.


Im Idealfall sind dies alles Laufzeitabhängigkeiten, die in das Bundle fallen (oder zumindest die massivsten davon, wie React-Dom oder Lodash), und nicht nur ihre eigenen (erste Ebene), sondern auch transitive (Abhängigkeitsabhängigkeiten). In Zukunft müssen Sie diese Liste selbst pflegen.


(2) Schreiben Sie für ausgewählte Module die Pfade zu ihren kompilierten Versionen aus.


Anstatt Abhängigkeiten zu überspringen, müssen Sie dem Kollektor eine Alternative bereitstellen, und diese Alternative sollte nicht von der Umgebung abhängen - module.exports , require , process , import usw. Für diese Rolle sind vorkompilierte (nicht unbedingt minimierte) Einzeldateimodule geeignet, die normalerweise im dist-Ordner innerhalb der Abhängigkeitsquellen liegen. Um sie zu finden, müssen Sie zu node_modules gehen. Für Axios sieht der Pfad zum kompilierten Modul beispielsweise folgendermaßen aus: node_modules/axios/dist/axios.js .


(3) Verwenden Sie in der Webpack-Konfiguration die Option resolve.alias, um Importe durch Abhängigkeitsnamen durch direkte Importe von Dateien zu ersetzen, deren Pfade im vorherigen Schritt geschrieben wurden.


Zum Beispiel:


 { resolve: { alias: { axios: path.resolve( __dirname, 'node_modules/dist/axios.min.js' ), ... } } } 

Hier liegt ein großer Fehler vor: Wenn sich Ihr Code oder der Code Ihrer Abhängigkeiten nicht auf den Standardeinstiegspunkt (Indexdatei, Hauptfeld in package.json ) package.json , sondern auf eine bestimmte Datei innerhalb der Abhängigkeitsquellen oder wenn die Abhängigkeit als ES-Modul exportiert wird oder wenn Der Auflösungsprozess stört etwas (z. B. Babel-Plugin-Transform-Importe). Die gesamte Idee kann fehlschlagen. Das Bundle wird zusammengesetzt, aber die Anwendung wird unterbrochen.


(4) Verwenden Sie in der Webpack-Konfiguration die Option module.noParse, um das Parsen vorkompilierter Module zu überspringen, die von den Pfaden aus Schritt 2 mithilfe regulärer Ausdrücke angefordert wurden.


Zum Beispiel:


 { module: { noParse: [ new RegExp('node_modules/dist/axios.min.js'), ... ] } } 

Fazit: Auf dem Papier sieht die Methode vielversprechend aus, aber ein nicht triviales Setup mit Fallstricken erhöht zumindest die Implementierungskosten und verringert zumindest die Vorteile.


Eine Alternative mit einem ähnlichen Funktionsprinzip ist die Verwendung der externals Option. In diesem Fall müssen Sie unabhängig voneinander Links zu externen Skripten in die HTML-Datei einfügen und sogar mit den erforderlichen Abhängigkeitsversionen, die package.json entsprechen.


- Trennen Sie selten wechselnden Code in ein separates Bundle und kompilieren Sie ihn nur einmal


Sicher haben Sie von DllPlugin gehört . Mit ihm können Sie aktiv ändernden Code (Ihre Anwendung) und selten ändernden Code (z. B. Abhängigkeiten) in verschiedene Assemblys verteilen. Sobald das zusammengestellte Abhängigkeitsbündel (dieselbe DLL) einfach mit der Anwendungsassembly verbunden ist, spart dies Zeit.


Es sieht allgemein so aus:


  1. Um die DLL zu erstellen, wird eine separate Webpack-Konfiguration erstellt, die erforderlichen Module werden als Einstiegspunkte verbunden.
  2. Der Build beginnt mit dieser Konfiguration. DllPlugin generiert ein DLL-Bundle und eine Manifestdatei mit Kartennamen und Modulpfaden.
  3. DllReferencePlugin wird der Konfiguration der Hauptassembly hinzugefügt, an die das Manifest übergeben wird.
  4. Importe von Abhängigkeiten, die während der Assemblierung in DLLs gerendert wurden, werden mithilfe des Manifests auf bereits kompilierte Module abgebildet.

Sie können etwas mehr im Artikel hier lesen.


Wenn Sie diesen Ansatz anwenden, werden Sie schnell eine Reihe von Nachteilen feststellen:


  • Die DLL-Assembly ist von der Hauptassembly isoliert und muss separat verwaltet werden: Bereiten Sie eine spezielle Konfiguration vor und starten Sie sie jedes Mal neu, wenn ein Zweig gewechselt wird oder sich eine Abhängigkeit ändert.
  • Da die DLL nicht mit den Artefakten der Hauptassembly verknüpft ist, muss sie manuell mit den anderen Assets in den Ordner kopiert und mit einem der folgenden Plugins in die HTML-Datei aufgenommen werden: 1 , 2 .
  • Die Liste der Abhängigkeiten, die für die Aufnahme in das DLL-Bundle vorgesehen sind, muss manuell auf dem neuesten Stand gehalten werden.
  • Das Traurigste: Baumschütteln wird nicht auf das DLL-Bundle angewendet. Theoretisch ist die Option entryOnly dafür vorgesehen, sie haben jedoch vergessen, sie zu dokumentieren.

Sie können das Boilerplate entfernen und das erste Problem (sowie das zweite, wenn Sie das HTML-Webpack-Plugin v3 verwenden - es funktioniert nicht mit Version 4) mit AutoDllPlugin lösen . Die Option entryOnly für das entryOnly das "unter der Haube" verwendet wird, wird jedoch immer noch nicht unterstützt, und der Autor des Plugins bezweifelt, dass es angesichts des kommenden Webpacks 5 ratsam ist, seine Idee zu verwenden.


Verschiedenes


Aktualisieren Sie Ihre Software und Abhängigkeiten regelmäßig. Node.js, npm / yarn (webpack, Babel .) . , changelog, issues, , .


PostCSS postcss-preset-env stage, . , stage-3, Custom Properties, stage-4 13%.


Sass (node-sass, sass-loader), Dart Sass ( Sass Dart, JS) fast-sass-loader . , . — dart-sass , node-sass, JS, libsass.


Dart Sass sass-loader . Sass fibers.


CSS-, dev-. - , , , .


:


 { loader: 'css-loader', options: { modules: true, localIdentName: isDev ? '[path][name][local]' : '[hash:base64:5]' } } 

, , : .


, - webpack PrefetchPlugin , , — . webpack issues , . ?


  1. . CLI- --json , . . , , dev- .
  2. - Hints.
  3. , “Long module build chains”. , — PrefetchPlugin .
  4. PrefetchPlugin. . StackOverflow .

: .



, (TypeScript, Angular .) — !



, , , .


Source: https://habr.com/ru/post/de451146/


All Articles