Verbessern Sie die Leistung, indem Sie moderne JavaScript-Abhängigkeiten und -Ausgabe aktivieren.
Über 90% der Browser können modernes JavaScript ausführen, Die Verbreitung von veraltetem JavaScript ist nach wie vor eine große Ursache für Leistungsprobleme im Web.
Modernes JavaScript
Modernes JavaScript ist nicht als Code gekennzeichnet, der in einem speziellen ECMAScript geschrieben wurde. die Spezifikationsversion an, sondern in einer Syntax, die von allen modernen Browser. Moderne Webbrowser wie Chrome, Edge, Firefox und Safari über 90% des Browsermarkts. unterschiedliche Browser, die auf den gleichen Rendering-Modulen basieren, bilden ein weitere 5%. Das bedeutet, dass 95% des weltweiten Web-Traffics von Browsern stammt. die die gängigsten JavaScript-Sprachfunktionen der letzten 10 Jahren, einschließlich:
- Klassen (ES2015)
- Pfeilfunktionen (ES2015)
- Generatoren (ES2015)
- Block-Bereich (ES2015)
- Zerstörung (ES2015)
- Parameter für Ruhe und Streuung (ES2015)
- Objekt-Abkürzung (ES2015)
- Async/await (ES2017)
Features in neueren Versionen der Sprachspezifikation haben in der Regel weniger in allen modernen Browsern. Viele ES2020 und ES2021 werden nur von 70% des Browsermarktes unterstützt. aber nicht so sehr, dass man sich direkt auf diese Funktionen verlassen kann. Dieses bedeutet, dass obwohl „modern“ JavaScript ist ein bewegliches Ziel, ES2017 bietet größte Bandbreite an Browserkompatibilität und die meisten der gängigen modernen Syntaxfunktionen enthalten. Mit anderen Worten: ES2017 ist der heutigen Syntax am nächsten.
Altes JavaScript
Legacy-JavaScript ist Code, der ausdrücklich vermeidet, die oben aufgeführten Programmiersprachen zu verwenden. Funktionen. Die meisten Entwickler schreiben ihren Quellcode mit moderner Syntax, aber alles in die Legacy-Syntax zu kompilieren, um die Browserunterstützung zu verbessern. Kompilieren gegenüber der Legacy-Syntax verbessert den Browser-Support, aber das ist oft der Fall. als wir erkennen. In vielen Fällen erhöht sich die Unterstützung von etwa 95 % der auf 98% reduzieren, wobei erhebliche Kosten anfallen:
Älteres JavaScript ist in der Regel etwa 20% größer und langsamer als entsprechenden modernen Code. Tools-Mängel und Fehlkonfigurationen sind häufig um diese Lücke weiter zu vergrößern.
Installierte Bibliotheken machen bis zu 90% der typischen Produktionsversionen JavaScript-Code. Bibliothekscode führt zu einem noch höheren Legacy-JavaScript-Code Overhead aufgrund von Polyfill und Hilfsduplizierung, die vermieden werden könnten indem Sie modernen Code veröffentlichen.
Modernes JavaScript in npm
Seit Kurzem ist in Node.js ein "exports"
-Feld standardisiert,
Einstiegspunkte für ein Paket:
{
"exports": "./index.js"
}
Module, auf die im Feld "exports"
verwiesen wird, bedeuten eine Knotenversion von mindestens
12.8, unterstützt ES2019. Das bedeutet, dass jedes Modul, auf das mithilfe der
Das Feld "exports"
kann in modernem JavaScript geschrieben werden. Paketnutzer müssen
gehen davon aus, dass Module mit einem "exports"
-Feld modernen Code enthalten, und transpilieren, wenn
notwendig ist.
Nur modern
Wenn Sie ein Paket mit modernem Code veröffentlichen und es
die Transkription verarbeitet, wenn er sie als Abhängigkeit verwendet. Verwenden Sie nur die
"exports"
.
{
"name": "foo",
"exports": "./modern.js"
}
Modern mit altem Fallback
Verwenden Sie das Feld "exports"
zusammen mit "main"
, um Ihr Paket zu veröffentlichen.
mit modernem Code, sondern auch mit einem ES5- und CommonJS-Fallback für ältere Versionen
Browser.
{
"name": "foo",
"exports": "./modern.js",
"main": "./legacy.cjs"
}
Modern mit Legacy-Fallback- und ESM-Bundler-Optimierungen
Mit dem Feld "module"
kann nicht nur ein CommonJS-Einstiegspunkt für Fallbacks definiert werden,
auf ein ähnliches Legacy-Fallback-Bundle verweist, das jedoch
Syntax des JavaScript-Moduls (import
und export
)
{
"name": "foo",
"exports": "./modern.js",
"main": "./legacy.cjs",
"module": "./module.js"
}
Viele Bundler, z. B. Webpack und Rollup, nutzen dieses Feld, um ihre Vorteile
Funktionen des Moduls
Beben von Bäumen.
Dies ist immer noch ein Legacy-Bundle, das keinen modernen Code enthält.
import
/export
-Syntax. Verwenden Sie diesen Ansatz, um modernen Code mit einer
alte Fallback-Lösung, die immer noch für die Bündelung optimiert ist.
Modernes JavaScript in Anwendungen
Abhängigkeiten von Drittanbietern machen den überwiegenden Teil der typischen Produktionsumgebungen aus. JavaScript-Code in Webanwendungen. Während npm-Abhängigkeiten in der Vergangenheit ES5-Syntax veröffentlicht wurde, gilt dies nicht mehr Risiken Abhängigkeitsupdates zum Ausfall des Browsersupports in Ihrer Anwendung.
Da immer mehr npm-Pakete auf modernes JavaScript umgestellt werden, müssen die Build-Tools entsprechend eingerichtet sein. Es gibt eine gute Wahrscheinlichkeit, dass einige der npm-Pakete, auf die Sie sich verlassen, bereits moderne Sprachfunktionen. Es gibt mehrere Möglichkeiten, modernen Code zu verwenden ohne dass Ihre Anwendung in älteren Browsern unterbrochen wird. dass das Build-System Abhängigkeiten in dieselbe Syntax überträgt, als Quellcode festlegen.
Webpack
Ab Webpack 5 kann konfiguriert werden, welche Syntax das Webpack verwenden soll wenn Sie Code für Bundles und Module generieren. Dabei wird Ihr oder Abhängigkeiten auswirkt, betrifft nur den „Kleber“ von Webpack generiert. Fügen Sie einen Parameter hinzu, um das Ziel für die Browserunterstützung anzugeben. browserslist-Konfiguration an Ihr Projekt oder direkt in Ihrer Webpack-Konfiguration:
module.exports = {
target: ['web', 'es2017'],
};
Webpack kann auch so konfiguriert werden, dass optimierte Bundles generiert werden,
Weglassen unnötiger Wrapper-Funktionen beim Targeting auf moderne ES-Module
zu verbessern. Dadurch wird Webpack auch so konfiguriert, dass Code-Split-Bundles mit
<script type="module">
module.exports = {
target: ['web', 'es2017'],
output: {
module: true,
},
experiments: {
outputModule: true,
},
};
Es gibt mehrere Webpack-Plug-ins, mit denen modernen JavaScript-Code kompilieren und versenden und gleichzeitig ältere Browser unterstützen, Optimize-Plug-in und BabelEsmPlugin.
Optimize-Plug-in
Das Optimize-Plug-in ist ein Webpack Plug-in, das endgültigen gebündelten Code von modernem in Legacy-JavaScript umwandelt statt auf jede einzelne Quelldatei. Es ist eine eigenständige Einrichtung, die dass alles modernes JavaScript ist, spezielle Verzweigungen für mehrere Ausgaben oder Syntaxen.
Da das Optimize-Plug-in mit Bundles und nicht mit einzelnen Modulen ausgeführt wird, den Code Ihrer Anwendung und Ihre Abhängigkeiten gleichermaßen verarbeitet. So können Sie moderne JavaScript-Abhängigkeiten von npm verwenden, da deren Code gebündelt und in die richtige Syntax transpiliert wird. Es kann auch schneller sein als herkömmliche Lösungen, bei denen zwei Kompilierungsschritte erforderlich sind, separate Sets für moderne und ältere Browser. Die beiden Sets sind die die mithilfe der Funktion Modul-/nomodule-Muster an.
// webpack.config.js
const OptimizePlugin = require('optimize-plugin');
module.exports = {
// ...
plugins: [new OptimizePlugin()],
};
Optimize Plugin
kann schneller und effizienter als benutzerdefiniertes Webpack sein
Konfigurationen, in denen modernen und Legacy-Code in der Regel separat gebündelt werden. Es
kümmert sich auch um die Ausführung von Babel für Sie und reduziert
Sets mit Terser mit separaten optimalen Einstellungen für
moderne und Legacy-Ausgaben zu optimieren. Schließlich werden Polyfills, die für die generierten
Legacy-Bundles werden in ein dediziertes Skript extrahiert, damit sie
dupliziert oder in neueren Browsern unnötigerweise geladen werden.
BabelEsmPlugin
BabelEsmPlugin ist ein Webpack. das zusammen mit @babel/preset-env zum Generieren moderner Versionen vorhandener Bundles, um weniger transpilierten Code an moderne Browser. Es ist die beliebteste Standardlösung für Module/nomodule, verwendet von Next.js und Preact-Befehlszeile.
// webpack.config.js
const BabelEsmPlugin = require('babel-esm-plugin');
module.exports = {
//...
module: {
rules: [
// your existing babel-loader configuration:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
plugins: [new BabelEsmPlugin()],
};
BabelEsmPlugin
unterstützt eine Vielzahl von Webpack-Konfigurationen,
zwei größtenteils
separate Builds Ihrer Anwendung ausführt. Zweimal Kompilierung kann eine
für große Anwendungen etwas mehr Zeit. Mit dieser Technik
BabelEsmPlugin
zur nahtlosen Integration in vorhandene Webpack-Konfigurationen
und macht sie zu einer der bequemsten Optionen, die es gibt.
Babel-Loader zum Transpilieren von node_modules konfigurieren
Wenn Sie babel-loader
ohne eines der beiden vorherigen Plug-ins verwenden,
ist ein wichtiger Schritt erforderlich, um
modernes JavaScript npm zu nutzen.
Module. Das Definieren von zwei separaten babel-loader
-Konfigurationen ermöglicht
zur automatischen Kompilierung moderner Sprachfunktionen in node_modules
, um
ES2017, während Sie mit dem Babel-Tool Ihren eigenen Code
Plug-ins und Voreinstellungen, die Sie in der Konfiguration Ihres Projekts definiert haben. Das ist nicht
Generieren moderner und Legacy-Bundles für eine Modul-/Nomodule-Einrichtung
ermöglichen die Installation und Verwendung von npm-Paketen, die modernes JavaScript
ohne dass dabei ältere Browser beeinträchtigt werden.
webpack-plugin-modern-npm
verwendet dieses Verfahren, um npm-Abhängigkeiten zu kompilieren, die das Feld "exports"
haben
in package.json
enthalten, da diese moderne Syntax enthalten können:
// webpack.config.js
const ModernNpmPlugin = require('webpack-plugin-modern-npm');
module.exports = {
plugins: [
// auto-transpile modern stuff found in node_modules
new ModernNpmPlugin(),
],
};
Alternativ kannst du das Verfahren manuell in deinem Webpack implementieren.
Konfiguration, indem Sie nach dem Feld "exports"
in package.json
von
sobald er abgeschlossen ist. Der Einfachheit halber wird das Caching
könnte wie folgt aussehen:
// webpack.config.js
module.exports = {
module: {
rules: [
// Transpile for your own first-party code:
{
test: /\.js$/i,
loader: 'babel-loader',
exclude: /node_modules/,
},
// Transpile modern dependencies:
{
test: /\.js$/i,
include(file) {
let dir = file.match(/^.*[/\\]node_modules[/\\](@.*?[/\\])?.*?[/\\]/);
try {
return dir && !!require(dir[0] + 'package.json').exports;
} catch (e) {}
},
use: {
loader: 'babel-loader',
options: {
babelrc: false,
configFile: false,
presets: ['@babel/preset-env'],
},
},
},
],
},
};
Wenn Sie diesen Ansatz verwenden, müssen Sie sicherstellen, dass die moderne Syntax von den
den Minifier an. Beide Terser
und uglify-es
können Sie {ecma: 2017}
angeben, um die
Generieren der ES2017-Syntax während der Komprimierung und Formatierung.
Auf einen Blick
Rollup bietet integrierte Unterstützung für das Generieren mehrerer Sets von Bundles als Teil eines und generiert standardmäßig modernen Code. Dadurch kann Sammel-Property können so konfiguriert werden, dass mit den offiziellen Plug-ins moderne und Legacy-Bundles generiert werden. die Sie wahrscheinlich bereits nutzen.
@rollup/plugin-babel
Wenn Sie Rollup verwenden,
getBabelOutputPlugin()
-Methode
(bereitgestellt vom Rollup-Dienst
offizielles Babel-Plug-in)
wandelt den Code in generierten Bundles statt in einzelnen Quellmodulen um.
Rollup bietet integrierte Unterstützung für das Generieren mehrerer Sets von Bundles als Teil eines
einen einzelnen Build mit jeweils eigenen Plug-ins erstellen. Damit können Sie
verschiedene Bundles für moderne und Legacy-Anwendungen.
Konfiguration des Babel-Ausgabe-Plug-ins:
// rollup.config.js
import {getBabelOutputPlugin} from '@rollup/plugin-babel';
export default {
input: 'src/index.js',
output: [
// modern bundles:
{
format: 'es',
plugins: [
getBabelOutputPlugin({
presets: [
[
'@babel/preset-env',
{
targets: {esmodules: true},
bugfixes: true,
loose: true,
},
],
],
}),
],
},
// legacy (ES5) bundles:
{
format: 'amd',
entryFileNames: '[name].legacy.js',
chunkFileNames: '[name]-[hash].legacy.js',
plugins: [
getBabelOutputPlugin({
presets: ['@babel/preset-env'],
}),
],
},
],
};
Zusätzliche Build-Tools
Rollup und Webpack sind hoch konfigurierbar. Das bedeutet in der Regel, dass jedes Projekt muss seine Konfiguration aktualisieren, um moderne JavaScript-Syntax in Abhängigkeiten zu ermöglichen. Es gibt auch übergeordnete Build-Tools, die Konventionen und Standardeinstellungen wie Parcel, Snowpack, Vite und WMR. Die meisten dieser Tools gehen davon aus, dass npm-Abhängigkeiten moderne Syntax enthalten können, und übertragen sie in die entsprechenden Syntaxebenen beim Erstellen für die Produktion.
Neben den speziellen Plug-ins für Webpack und Rollup Sets mit alten Fallbacks können jedem Projekt mit devolution. Devolution ist ein eigenständiges Tool, das die Ausgabe eines Build-Systems in Legacy-Umgebungen JavaScript-Varianten, wodurch Bündelung und Transformationen eine moderne Ausgabeziel.