더 빠른 애플리케이션을 위한 최신 JavaScript 게시, 제공, 설치

최신 JavaScript 종속 항목 및 출력을 사용 설정하여 성능을 향상하세요.

90% 이상의 브라우저가 최신 자바스크립트를 실행할 수 있지만 기존 JavaScript의 보급은 여전히 성능 문제의 큰 원인 자세히 알아보세요.

최신 JavaScript

최신 자바스크립트는 특정 ECMAScript로 작성된 코드로 특성이 지정되지 않음 모든 최신 버전에서 지원하는 구문에 있습니다. Chrome, Edge, Firefox, Safari와 같은 최신 웹브라우저는 브라우저 시장의 90% 이상 동일한 기본 렌더링 엔진을 사용하는 서로 다른 브라우저는 추가 5% 전 세계 웹 트래픽의 95% 가 브라우저에서 발생합니다. 최근 10개 버전으로 가장 많이 사용된 JavaScript 언어 기능을 지원하는 년.

  • 클래스 (ES2015)
  • 화살표 함수 (ES2015)
  • 발전기 (ES2015)
  • 블록 범위 지정 (ES2015)
  • 디스트럭처링 (ES2015)
  • 휴식 및 분산 매개변수 (ES2015)
  • 객체 약식 (ES2015)
  • Async/await (ES2017)

언어 사양 최신 버전의 기능은 일반적으로 최신 브라우저에서 일관되게 지원됩니다. 예를 들어 많은 ES2020 및 ES2021이 기능은 현재 브라우저 시장의 70% 에서만 지원됩니다. 이러한 기능에 직접 의존하는 것은 안전하지 않습니다. 이 비록 '현대적'인 JavaScript는 움직이는 과녁이지만 ES2017은 광범위한 브라우저 호환성 일반적으로 사용되는 최신 구문 기능을 대부분 포함할 수 있습니다. 즉, ES2017은 현재 최신 구문에 가장 가깝습니다.

기존 JavaScript

기존 JavaScript는 특히 위의 모든 언어를 사용하지 않도록 하는 코드입니다. 기능을 살펴보겠습니다 대부분의 개발자는 최신 구문을 사용하여 소스 코드를 작성하지만 브라우저 지원을 향상하기 위해 모든 것을 기존 구문으로 컴파일합니다. 컴파일 를 사용하면 브라우저 지원이 증가하지만 효과는 종종 더 작다는 것을 깨달았습니다. 대부분의 경우 지원이 약 95%에서 98% 까지 확장하면서도 상당한 비용이 발생합니다.

  • 기존 JavaScript는 일반적으로 기존 JavaScript보다 약 20% 더 크고 느립니다. 사용할 수 있습니다. 자주 발생하는 도구 결함 및 구성 오류 이 격차는 더욱 벌어집니다

  • 설치된 라이브러리가 일반적인 프로덕션의 90% 를 차지함 JavaScript 코드 라이브러리 코드로 인해 훨씬 더 높은 기존 JavaScript가 발생 폴리필 및 도우미 중복으로 인한 오버헤드 최신 코드를 게시함으로써

npm의 최신 JavaScript

최근에 Node.js는 "exports" 필드를 표준화하여 패키지의 진입점:

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

"exports" 필드에서 참조하는 모듈은 다음 노드 버전을 의미합니다. 12.8(ES2019 지원) 즉, "exports" 필드는 최신 JavaScript로 작성할 수 있습니다. 패키지 소비자는 "exports" 필드가 있는 모듈에 최신 코드가 포함되어 있고 다음과 같은 경우 트랜스파일이라고 가정합니다. 있습니다.

현대만

최신 코드를 사용하여 패키지를 게시하고 소비자가 이를 종속 항목으로 사용할 때 트랜스파일링을 처리하려면 "exports" 필드

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

레거시 대체에 현대적인 기능 포함

패키지를 게시하려면 "main"와 함께 "exports" 필드를 사용하세요. 최신 코드를 사용하지만 레거시의 ES5 + CommonJS 대체도 포함함 있습니다.

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

레거시 대체 및 ESM 번들러 최적화가 적용된 최신 기능

"module" 필드는 대체 CommonJS 진입점을 정의하는 것 외에도 유사한 레거시 대체 번들을 가리키는 데 사용되지만, JavaScript 모듈 문법 (importexport)

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

webpack 및 Rollup과 같은 많은 번들러는 이 필드를 사용하여 모듈 기능을 자세히 살펴보고 나무 쉐이킹이라고 합니다. 이것은 여전히 import/export 문법이 있으므로 이 접근 방식을 사용하여 최신 코드를 여전히 번들에 최적화된 기존 대체

애플리케이션의 최신 JavaScript

서드 파티 종속 항목이 일반적인 프로덕션의 대부분을 구성 웹 애플리케이션의 JavaScript 코드 이전에는 npm 종속 항목이 기존 ES5 구문으로 게시되었지만, 이것은 더 이상 안전한 가정이 아니며 종속 항목 업데이트가 애플리케이션의 브라우저 지원을 중단시킬 위험이 있습니다.

점점 더 많은 npm 패키지가 최신 JavaScript로 전환됨에 따라 이를 처리하도록 빌드 도구가 설정되어 있는지 확인하는 것이 중요합니다. 이 사용하는 npm 패키지 중 일부가 이미 최신 버전의 npm을 사용하고 있을 가능성이 높습니다. 언어 기능을 사용할 수 있습니다. 최신 코드를 사용하는 데 사용할 수 있는 여러 가지 옵션이 있음 npm에서 최신 버전을 가져올 수 있지만, 일반적인 빌드 시스템에서 종속 항목을 동일한 구문으로 변환 컴파일하도록 타겟을 소스 코드로 사용하세요.

webpack

이제 webpack 5를 통해 webpack에서 사용할 구문을 구성할 수 있습니다. 코드 생성 시 참고하시기 바랍니다. 이렇게 해도 종속 항목이 있는 경우 '결합'에만 영향을 웹팩에서 생성하는 코드입니다. 브라우저 지원 대상을 지정하려면 브라우저 목록 구성 webpack 구성에서 직접 업데이트합니다.

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

또한 웹팩을 구성하여 최신 ES 모듈을 타겟팅할 때 불필요한 래퍼 함수 생략 환경입니다 또한 다음을 사용하여 코드 분할 번들을 로드하도록 webpack을 구성합니다. <script type="module">

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

다양한 webpack 플러그인을 사용하여 레거시 브라우저를 지원하면서도 최신 JavaScript를 컴파일하고 제공할 수 있습니다. 도구 플러그인, BabelEsmPlugin 등의 코드를 사용할 수 있습니다.

최적화 도구 플러그인

최적화 도구 플러그인은 웹팩입니다. 최종 번들 코드를 최신 JavaScript에서 기존 JavaScript로 변환하는 플러그인 각 개별 소스 파일 대신 독립 실행형 설정으로, 웹팩 구성에서 모든 것이 최신 자바스크립트이며 여러 출력 또는 문법을 위한 특수 브랜치입니다.

최적화 도구 플러그인은 개별 모듈이 아닌 번들에서 작동하므로 애플리케이션의 코드와 종속 항목을 동일하게 처리합니다. 이렇게 하면 최신 JavaScript 종속 항목을 안전하게 사용할 수 있습니다. 올바른 구문으로 변환 컴파일됩니다 또한 두 가지 컴파일 단계를 수반하는 기존 솔루션을 사용하면서 별도의 번들을 제공합니다. 두 번들 세트는 API를 사용하여 로드하도록 module/nomodule 패턴과 일치해야 합니다.

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

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

Optimize Plugin는 맞춤 webpack보다 더 빠르고 효율적입니다. 구성에는 일반적으로 최신 코드와 기존 코드가 별도로 번들화됩니다. 그것은 Babel 실행을 자동으로 처리하며 별도의 최적 설정과 함께 Terser를 사용하는 번들 최신 출력과 레거시 출력을 모니터링할 수 있습니다 마지막으로, 생성된 피처스토어에 필요한 폴리필은 기존 번들은 전용 스크립트로 추출되므로 최신 브라우저에서 중복되거나 불필요하게 로드되는 경우가 여기에 해당합니다.

<ph type="x-smartling-placeholder">
</ph>
비교: 소스 모듈을 두 번 트랜스파일하는 것과 생성된 번들을 트랜스파일하는 것 비교

BabelEsmPlugin

BabelEsmPlugin은 웹팩입니다. Google 모바일 광고 SDK와 함께 작동하는 @babel/preset-env 기존 번들의 최신 버전을 생성하여 덜 트랜스파일된 코드를 최신 브라우저입니다. 가장 널리 사용되는 기성 솔루션이며 module/nomodule: Next.js에서 사용 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는 다양한 webpack 구성을 지원합니다. 크게 별개로 애플리케이션 빌드를 두 개 실행합니다. 두 번 컴파일하려면 약간의 추가 시간이 필요하지만 이 기법을 사용하면 BabelEsmPlugin: 기존 webpack 구성에 원활하게 통합 사용 가능한 가장 편리한 옵션 중 하나로 만듭니다

node_modules를 트랜스파일하도록 babel-loader 구성

위의 두 플러그인 중 하나 없이 babel-loader를 사용하는 경우 최신 JavaScript npm을 사용하려면 중요한 단계가 있습니다. 모듈을 마칩니다 두 개의 개별 babel-loader 구성을 정의하면 가능함 를 사용하면 node_modules에 있는 최신 언어 기능을 자동으로 컴파일하여 ES2017을 실행하는 동시에 자체 퍼스트 파티 코드를 Babel로 트랜스파일링함 사전 설정을 지정합니다. 이것은 모듈/nomodule 설정을 위한 최신 및 레거시 번들을 생성하지만 최신 JavaScript가 포함된 npm 패키지 설치 및 사용 가능 할 수 있습니다.

webpack-plugin-modern-npm 이 기법을 사용하여 "exports" 필드가 있는 npm 종속 항목을 컴파일합니다. 최신 문법이 포함될 수 있으므로 다음과 같이 package.json를 반환합니다.

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

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

또는 webpack에 기술을 직접 구현할 수 있습니다. package.json"exports" 필드를 확인하여 구성을 모듈을 해결할 수 있습니다 간결성을 위해 캐싱 생략, 구현은 다음과 같을 수 있습니다.

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

이 접근 방식을 사용할 때는 최신 문법이 최소화합니다. 둘 다 Terseruglify-es 보존하기 위해 {ecma: 2017}를 지정하는 옵션이 있고 경우에 따라 압축 및 형식 지정 중에 ES2017 구문을 생성합니다.

롤업

Rollup에는 Cloud Functions의 일부로 여러 번들 세트를 생성하기 위한 지원이 기본 제공됩니다. 빌드하며, 기본적으로 최신 코드를 생성합니다. 따라서 Rollup은 공식 플러그인으로 최신 및 레거시 번들을 생성하도록 구성 아마도 이미 사용 중인 것입니다.

@rollup/plugin-babel

Rollup을 사용하는 경우 getBabelOutputPlugin() 메서드 (Rollup의 공식 Babel 플러그인을 참고하세요. 개별 소스 모듈이 아닌 생성된 번들의 코드를 변환합니다. Rollup에는 Cloud Functions의 일부로 여러 번들 세트를 생성하기 위한 지원이 기본 제공됩니다. 각 빌드에 자체 플러그인이 있는 단일 빌드입니다. 이것을 사용하여 현대 및 레거시의 다양한 번들을 서로 다른 Babel 출력 플러그인 구성:

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

추가 빌드 도구

Rollup 및 webpack은 구성이 용이합니다. 이는 일반적으로 각 프로젝트라는 의미입니다. 종속 항목에서 최신 JavaScript 구문을 사용 설정하도록 구성을 업데이트해야 합니다. 또한 규칙과 기본값을 선호하는 상위 수준의 빌드 도구도 있습니다. Parcel, Snowpack, Vite, WMR과 같은 구성을 지원합니다. 이러한 도구의 대부분은 npm 종속 항목에 최신 구문이 포함될 수 있다고 가정하고 적절한 문법 수준을 사용해야 합니다

Webpack 및 Rollup 전용 플러그인 외에도 기존 대체가 있는 번들은 개발입니다. 디볼루션은 빌드 시스템의 출력을 변환하여 레거시를 생성하는 독립형 도구 번들 및 변환이 최신 코드라고 가정할 수 있는 JavaScript 변형 출력 타겟과 일치합니다.