Daha hızlı uygulamalar için modern JavaScript'i yayınlayın, gönderin ve yükleyin

Modern JavaScript bağımlılıklarını ve çıkışını etkinleştirerek performansı artırın.

Tarayıcıların% 90'ından fazlası modern JavaScript'i çalıştırabiliyor, ancak yaygınlığı, performans problemlerinin büyük bir kaynağı olmaya devam ediyor bugün web'de kullanıma sunuyoruz.

Modern JavaScript

Modern JavaScript, belirli bir ECMAScript'te yazılmış kod olarak nitelendirilmez değil, tüm modern işletme sürümleri tarafından desteklenen söz diziminde izin verir. Chrome, Edge, Firefox ve Safari gibi modern web tarayıcıları tarayıcı pazarının% 90'ından fazlasına ve aynı temel oluşturma motorlarına dayanan farklı tarayıcılar ek %5. Bu, dünyadaki web trafiğinin% 95'inin tarayıcılardan geldiği Google Analytics 4'te tarama odaklı yıl, aşağıdakiler dahil:

  • Sınıflar (ES2015)
  • Ok işlevleri (ES2015)
  • Jeneratörler (ES2015)
  • Blok kapsamı (ES2015)
  • Yıkım (ES2015)
  • Dinlenme ve yayılma parametreleri (ES2015)
  • Nesne kısaltması (ES2015)
  • Eş zamansız/bekleme (ES2017)

Dil spesifikasyonunun yeni sürümlerindeki özellikler genellikle daha az modern tarayıcılarda tutarlı destek sunar. Örneğin, birçok ES2020 ve ES2021 tarayıcı pazarının yalnızca% 70'inde desteklendiğinden, doğrudan bu özellikleri kullanmanın güvenli olduğu kadar ileri gitmez. Bu “modern” olsa da JavaScript sürekli değişen bir hedef, ES2017 en geniş tarayıcı uyumluluğu yelpazesi ve yaygın olarak kullanılan modern söz dizimi özelliklerinin çoğunu içerir. Başka bir deyişle, ES2017 günümüzde modern söz dizimine en yakın olan sürümdür.

Eski JavaScript

Eski JavaScript, özellikle yukarıdaki dilin tümünün kullanılmasını önleyen koddur özellikleri. Çoğu geliştirici kaynak kodunu modern söz dizimi kullanarak yazar, ancak daha fazla tarayıcı desteği için her şeyi eski söz diziminde derleyin. Derleniyor eski söz diziminin değiştirilmesi tarayıcı desteğini artırır, ancak etkisi genellikle daha küçük olduğunu biliyor. Çoğu durumda, destek yaklaşık %95'ten itibaren %98'e yükseldi ve önemli bir maliyete yol açtı:

  • Eski JavaScript, JavaScript'e kıyasla genellikle% 20 daha büyük ve eşdeğer modern kod. Araç eksiklikleri ve sıklıkla yanlış yapılandırma daha da genişleteceğiz.

  • Yüklü kitaplıklar, tipik üretimin% 90'ını oluşturur JavaScript kodu. Kitaplık kodu daha da yüksek bir eski JavaScript kodu gerektirir nedeniyle ortaya çıkabilecek ek yük ve yardımcı kopya modern bir kod yayınlayın.

npm'de modern JavaScript

Node.js son zamanlarda bir "exports" alanını tanımlamak için bir paket için giriş noktaları:

{
  "exports": "./index.js"
}

"exports" alanı tarafından başvurulan modüller en az şu Düğüm sürümünü ima ediyor ES2019'u destekler. Bu, "exports" alanı, modern JavaScript'te yazılabilir. Paket tüketicileri, "exports" alanı olan modüllerin modern kod içerdiğini varsayın ve gerekir.

Yalnızca modern

Modern kod içeren bir paket yayınlamak ve bağımlılık olarak kullandıklarında metne dönüştürme işlemini halledecek şekilde "exports" alanı boş bırakılamaz.

{
  "name": "foo",
  "exports": "./modern.js"
}
.

Eski yedek ile modern

Paketinizi yayınlamak için "main" ile birlikte "exports" alanını kullanın modern kodu kullanır ancak eski için ES5 + CommonJS yedeğini içerir izin verir.

{
  "name": "foo",
  "exports": "./modern.js",
  "main": "./legacy.cjs"
}

Eski yedek ve ESM paketleyici optimizasyonlarıyla modern

"module" alanı, yedek bir CommonJS giriş noktası tanımlamaya ek olarak benzer bir eski yedek pakete işaret etmek için kullanılabilir ancak JavaScript modülü söz dizimi (import ve export).

{
  "name": "foo",
  "exports": "./modern.js",
  "main": "./legacy.cjs",
  "module": "./module.js"
}

Webpack ve Rollup gibi birçok paketleyici, avantajlardan yararlanmak için özelliklerini tanıtıp ağaç sallama. Bu, kendisi dışında herhangi bir modern kod içermeyen eski bir pakettir. import/export söz dizimi. Bu yaklaşımı kullanarak modern kodları gruplama için hâlâ optimize edilmiş eski yedek.

Uygulamalarda modern JavaScript

Üçüncü taraf bağımlılıkları, tipik üretimin büyük çoğunluğunu oluşturur Web uygulamalarındaki JavaScript kodu. npm bağımlılıkları geçmişte eski ES5 söz dizimi olarak yayınlanmışsa bu artık güvenli bir varsayım değildir risk bağımlılık güncellemeleri uygulamanızdaki tarayıcı desteğini bozar.

Modern JavaScript'e geçen npm paketlerinin sayısının artmasıyla birlikte derleme aracının bunları kullanacak şekilde ayarlandığından emin olmak önemlidir. Bir kullandığınız npm paketlerinden bazılarının zaten modern ve normal dil özellikleri. Modern kodu kullanmak için sunulan çeşitli seçenekler vardır uygulamanızı bozmadan, npm'den ayarlanır, ancak genel olarak temel fikir, derleme sisteminin bağımlılıkları aynı söz dizimine hedefini kaynak kodunuz olarak belirleyin.

web paketi

Webpack 5'ten itibaren, web paketinin hangi söz dizimini kullanacağını artık yapılandırabilirsiniz. paket ve modüller için kod oluştururken kullanılır. Bu işlem, bağımlılıkları değil, yalnızca "bağımlı" webpack tarafından oluşturulan kod. Tarayıcı desteği hedefini belirtmek için tarayıcı listesi yapılandırması projenize ekleyin veya bunu doğrudan web paketi yapılandırmanızda yapın:

module.exports = {
  target: ['web', 'es2017'],
};

Ayrıca, tek bir pakette sunulan optimize edilmiş paketler oluşturmak Modern ES Modüllerini hedeflerken gereksiz sarmalayıcı işlevlerini kullanmayın bahsedeceğim. Bu ayrıca, web paketini kullanarak kod bölümü paketlerinin yüklenmesini <script type="module">

module.exports = {
  target: ['web', 'es2017'],
  output: {
    module: true,
  },
  experiments: {
    outputModule: true,
  },
};

Web paketi eklentilerini kullanarak şu işlemleri yapabilirsiniz: modern JavaScript'i derleyip gönderirken eski tarayıcıları desteklemeye devam ederken, Örneğin Optimize Plugin ve BabelEsmEklentiler.

Optimize Eklentisi

Optimize Plugin, bir web paketidir gruplandırılmış nihai kodu modern JavaScript'ten eski JavaScript'e dönüştüren eklenti kaynak dosya dosya adı oluşturabilirsiniz. Bu, Google Analytics 4'teki API'lerin her şeyin modern JavaScript olduğunu varsayacak şekilde, web paketi yapılandırmanızda söz dizimini kullanabilirsiniz.

Optimize Eklentisi bağımsız modüller yerine paketler üzerinde çalıştığından uygulamanızın kodunu ve bağımlılarınızı eşit şekilde işler. Bu da, npm'deki modern JavaScript bağımlılıklarını kullanmak güvenlidir, çünkü bunların kodları doğru söz dizimine göre aktarabilirsiniz. Ayrıca daha hızlı iki derleme adımı içeren geleneksel çözümler üretirken modern ve eski tarayıcılar için ayrı paketlere sahip. Bu iki paket grubu kullanılarak yüklenecek şekilde tasarlanmıştır. modül/modül yok deseni.

// webpack.config.js
const OptimizePlugin = require('optimize-plugin');

module.exports = {
  // ...
  plugins: [new OptimizePlugin()],
};

Optimize Plugin, özel web paketinden daha hızlı ve daha verimli olabilir yapılandırmalarını kullanabilirsiniz. Google Babel'i çalıştırmayı da sağlar ve farklı optimum ayarlara sahip Terser'ı kullanan ve eski çıktılar üzerinde çalışmak lazım. Son olarak, oluşturulan tablodaki çoklu dolguları Eski paketler özel bir komut dosyasına çıkarılır, böylece hiçbir zaman yinelenen veya gereksiz yere yüklenmiştir.

Karşılaştırma: Kaynak modüllerinin iki kez aktarılması ile oluşturulan paketlerin dönüştürülmesi.

BabelEsmPlugin

BabelEsmPlugin, bir web paketidir birlikte çalışan bir eklenti olan @babel/preset-env adresine daha az aktarılan kod göndermek üzere mevcut paketlerin modern sürümlerini oluşturmak yardımcı olabilir. Bu, proje yöneticileri için en popüler kullanıma hazır çözümdür. modül/nomodule, Next.js ve Preact CLI.

// 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, çok çeşitli web paketi yapılandırmalarını destekler. Bunun nedeni, uygulamanızın büyük ölçüde ayrı iki derlemesini çalıştırır. İki defa derleme yapmak bir miktar fazladan zaman kazanacağını unutmayın. Ancak bu teknik, Mevcut web paketi yapılandırmalarıyla sorunsuz bir şekilde entegre olmak için BabelEsmPlugin en pratik seçeneklerden biri haline getiriyor.

Node_modules değerini dönüştürmek için babel-loader'ı yapılandırma

Önceki iki eklentiden biri olmadan babel-loader kullanıyorsanız modern JavaScript npm'yi kullanmak için önemli bir adım vardır modüllerinde yer alır. İki ayrı babel-loader yapılandırması tanımlayarak aşağıdakileri gerçekleştirebilirsiniz: node_modules dilinde bulunan modern dil özelliklerini otomatik olarak derlemek için ES2017 (Babel ile kendi birinci taraf kodunuzu dönüştürmeye devam ederken) projenizin yapılandırmasında tanımlanan eklentiler ve hazır ayarlar. Bu iletişim modül/nomodül kurulumu için modern ve eski paketler oluşturabilir, ancak modern JavaScript içeren npm paketlerinin yüklenmesini ve kullanılmasını mümkün kılar yardımcı olan bir self servis platformdur.

webpack-plugin-modern-npm bu tekniği, "exports" alanına sahip npm bağımlılıklarını derlemek için kullanır modern söz dizimi içerdikleri için package.json içinde belirtilir:

// webpack.config.js
const ModernNpmPlugin = require('webpack-plugin-modern-npm');

module.exports = {
  plugins: [
    // auto-transpile modern stuff found in node_modules
    new ModernNpmPlugin(),
  ],
};

Alternatif olarak, tekniği web paketinize manuel olarak uygulayabilirsiniz yapılandırmanın package.json içinde "exports" alanı olup olmadığını kontrol edin üzerinde çalıştığınız proje planı taslağınızı oluşturun. Kısalık için önbelleğe alma atlanır, özel uygulama aşağıdaki gibi görünebilir:

// 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'],
          },
        },
      },
    ],
  },
};

Bu yaklaşımı kullanırken, modern söz diziminin yardımcı olur. Her iki Terser ve uglify-es korumak ve bazı durumlarda korumak amacıyla {ecma: 2017} belirtme seçeneğine sahip olmak sıkıştırma ve biçimlendirme sırasında ES2017 söz dizimi oluşturur.

Birleşim

Toplayıcı, bir feed'in parçası olarak birden fazla paket grubu varsayılan olarak modern kod oluşturur. Sonuç olarak Rollup, resmi eklentilerle modern ve eski paketler oluşturacak şekilde yapılandırılmalıdır zaten kullanıyorsunuzdur.

@rollup/plugin-babel

Rollup kullanıyorsanız getBabelOutputPlugin() yöntem (Rollup'ın resmi Babel eklentisi) kodu, ayrı kaynak modüller yerine oluşturulmuş paketlere dönüştürür. Toplayıcı, bir feed'in parçası olarak birden fazla paket grubu her biri kendi eklentilerine sahip olan tek bir derleme oluşturun. Bunu proje boyunca her birini farklı bir eğitim paketinden geçirerek Babel çıkış eklentisi yapılandırması:

// 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'],
        }),
      ],
    },
  ],
};

Ek derleme araçları

Toplayıcı ve web paketi, yüksek düzeyde yapılandırılabilir. Bu nedenle, genellikle her proje , bağımlılarda modern JavaScript söz dizimini etkinleştirmek üzere yapılandırmasını güncellemelidir. Kuralları ve varsayılanları destekleyen daha üst düzey derleme araçları da vardır. Parcel, Snowpack, Vite ve WMR gibi yapılandırmalar kullanabilirsiniz. Bu araçların çoğu npm bağımlılıklarının modern söz dizimi içerdiklerini ve bunları uygun söz dizimi seviyelerine göre nasıl seçim yapılır?

Webpack ve Rollup'a özel eklentilere ek olarak, modern JavaScript eski yedekleri olan paketler, devolution. Gelişim, derleme sistemindeki çıkışı dönüştüren bağımsız bir araç Gruplandırma ve dönüştürmelerin modern bir anlayışa sahip olmasını sağlayan JavaScript varyantları çıktı hedefidir.