프로젝트에서 Baseline을 사용하는 방법

1. 소개

Baseline은 오늘날 상호 운용 가능하고 안전하게 사용할 수 있는 웹 기능에 관한 명확한 메시지를 제공하는 이니셔티브입니다. 이제 Baseline 도구의 발전 덕분에 프로젝트에서 Baseline을 Browserslist 쿼리로 직접 사용할 수 있으므로 도구 모음이 선택한 Baseline 타겟에 따라 코드 출력을 변경할 수 있습니다.

이 Codelab에서는 샘플 프로젝트에서 Baseline을 사용하는 방법과 특정 Baseline 타겟을 선택하도록 구성하는 방법을 알아봅니다. 선택한 기준선 타겟에 따라 프로젝트 도구 체인의 출력이 어떻게 달라지는지도 확인할 수 있습니다.

2. 로컬 머신에서 데모 설정

먼저 원하는 터미널 애플리케이션으로 이동하여 데모 저장소를 클론한 후 프로젝트 디렉터리로 이동합니다.

git clone git@github.com:GoogleChromeLabs/baseline-demos.git
cd baseline-demos/tooling/webpack-browserslist-config-baseline

이 시점에는 데모에 이미 Baseline이 통합되어 있지만 처음부터 시작하는 커밋을 확인해야 합니다.

git checkout 94f12e34

저장소를 클론했으므로 이제 데모를 실행할 수 있습니다. 이 프로젝트에서는 nvm를 사용하여 노드 버전 관리를 합니다. 최근 버전의 Node가 전역적으로 설치되어 있다면 이 단계를 완료하지 않아도 되지만 nvm를 사용하는 경우 다음 명령어를 실행하세요.

nvm install
nvm use

여기에서 프로젝트의 패키지를 설치합니다.

npm install

데모를 보려면 다음 명령어를 실행합니다.

npm start

그런 다음 http://localhost:8080으로 이동합니다. 데모 자체는 페이지 상단의 양식 필드를 사용하여 필터링할 수 있는 카드 목록입니다. 앱 자체는 기준선 기준에 도달한 기능을 혼합하여 사용합니다.

데모를 마친 후 언제든지 터미널로 이동하여 Ctrl+C를 눌러 데모 실행을 중지합니다.

3. 프로젝트에 Baseline을 통합하는 방법

이 데모는 시작 시 Browserslist 구성을 지정하지 않습니다. Browserslist는 도구 모음에 지원해야 하는 최소 브라우저 버전을 알려주는 간결한 쿼리 구문입니다. 예를 들어 last 3 years 쿼리를 사용하면 다양한 타겟이 지정됩니다. 이 데모에서는 browserslist-config-baseline라는 npm 패키지를 사용하여 도구 체인에서 사용할 수 있는 기준 목표와 일치하는 Browserslist 쿼리를 지정합니다.

시작하려면 다음과 같이 browserslist-config-baseline를 설치하세요.

npm install browserslist-config-baseline --save-dev

이 패키지를 설치하면 프로젝트에서 extends Browserslist 쿼리를 지정하여 기준 브라우저 목록으로 확인할 수 있습니다. 이러한 기준 목표는 다음 중 하나일 수 있습니다.

  • 이동 타겟: 새 브라우저가 출시됨에 따라 시간이 지남에 따라 업데이트됩니다.
    • 새로 제공되는 기준: 현재부터 30개월 전까지 핵심 브라우저 세트에 구현된 상호 운용 가능한 기능과 일치합니다.
    • 기준선 널리 사용 가능: 30개월 전에 핵심 브라우저 세트에 구현된 상호 운용 가능한 기능을 포함합니다.
  • 고정 타겟: 특정 시점의 브라우저 버전을 나타냅니다. 2016년부터 현재 연도까지의 연도로 표현됩니다.

먼저 browserslist-config-baseline를 사용하여 프로젝트의 이동하는 기준 널리 사용 가능한 타겟을 선택합니다. 이렇게 하려면 package.json를 열고 다음을 추가하세요.

"browserslist": "extends browserslist-config-baseline"

4. 다양한 기준 타겟을 선택하여 코드 출력의 변경사항 관찰

데모 프로젝트의 타겟으로 널리 사용 가능한 기준을 선택했습니다. 다음으로 프로젝트를 빌드합니다.

npm run build

@babel/preset-envdebug 옵션이 프로젝트의 babel.config.js에서 true로 지정되어 있으므로 추가 출력이 많습니다. 먼저 번들러 통계에서 CSS와 JavaScript의 크기를 확인합니다.

assets by status 213 KiB [emitted]
  asset js/home.5f3c5480.js 208 KiB [emitted] [immutable] [minimized] (name: home) 2 related assets
  asset css/home.20db50ef.css 3.64 KiB [emitted] [immutable] (name: home) 1 related asset
  asset index.html 564 bytes [emitted]

여기서 JavaScript 번들은 208KiB이고 CSS는 3.64KiB입니다. 이 프로젝트에서는 JavaScript 폴리필에 core-js을 사용하고 아직 완전히 상호 운용되지 않는 CSS 속성에 공급업체별 접두사를 적용하는 데 autoprefixer을 사용하기 때문입니다. core-jsautoprefixer은 모두 browserslist-config-baseline의 영향을 받습니다.

출력에서 또 다른 주의할 점은 Baseline Widely available에 대한 Browserslist 쿼리가 Browserslist 쿼리로 변환되는 방식입니다. 프로젝트에서는 다음과 같이 표시됩니다.

Using targets: {
  "chrome": "108",
  "edge": "108",
  "firefox": "108",
  "ios": "16",
  "safari": "16"
}

빌드 출력에서 core-js에 의해 삽입된 폴리필을 확인합니다.

The corejs3 polyfill added the following polyfills:
  es.iterator.constructor { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }
  es.iterator.filter { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }
  es.iterator.map { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }

기준선 타겟을 변경하면 이 출력이 변경될 수 있습니다. 더 엄격한 SLA로 인해 애플리케이션이 훨씬 오래된 브라우저를 지원해야 한다고 가정해 보겠습니다. 이 경우 더 보수적인 타겟을 선택할 가능성이 높습니다. package.json 파일에서 다음과 같이 Browserslist 구성을 변경합니다.

"browserslist": "extends browserslist-config-baseline/2016"

이렇게 하면 Baseline 2016이 타겟으로 선택되며 Browerslist 쿼리로 변환됩니다. 빌드를 다시 실행한 후에는 도구 모음 출력의 차이점을 확인할 수 있습니다.

npm run build

먼저 번들러 통계에서 프로젝트의 JavaScript 및 CSS 파일 크기의 변경사항을 확인합니다.

assets by status 237 KiB [emitted]
  asset js/home.b228612d.js 232 KiB [emitted] [immutable] [minimized] (name: home) 2 related assets
  asset css/home.0c3e4fd7.css 3.91 KiB [emitted] [immutable] (name: home) 1 related asset
  asset index.html 564 bytes [emitted]

JavaScript 번들의 크기가 약 30KiB 증가한 것을 확인할 수 있습니다. 이 프로젝트의 CSS는 2016년 기준 타겟에 따라 autoprefixer가 더 많은 공급업체 접두사를 추가했기 때문에 약간 더 큽니다. Browserslist 쿼리의 변경사항도 확인하세요.

Using targets: {
  "chrome": "53",
  "edge": "14",
  "firefox": "49",
  "ios": "10",
  "safari": "10"
}

널리 사용 가능한 기준 타겟과 비교하면 이러한 브라우저 버전은 훨씬 이전 버전입니다. 이 경우 타겟팅되는 Edge 버전은 Chromium 이전 버전입니다.

core-js에 의해 삽입된 폴리필도 변경됩니다. 이는 타겟으로 '기준 널리 사용 가능'을 선택했을 때보다 훨씬 많은 변경사항입니다.

The corejs3 polyfill added the following polyfills:
  es.array.filter { "edge":"14" }
  es.iterator.constructor { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.iterator.filter { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.object.to-string { "edge":"14", "firefox":"49" }
  es.array.includes { "firefox":"49" }
  es.string.includes { "edge":"14" }
  es.array.map { "firefox":"49" }
  es.iterator.map { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.symbol { "edge":"14", "firefox":"49" }
  es.symbol.description { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.array.iterator { "chrome":"53", "edge":"14", "firefox":"49" }
  web.dom-collections.iterator { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.array.push { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.regexp.to-string { "edge":"14" }
  es.array.from { "edge":"14", "firefox":"49" }
  es.regexp.exec { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.regexp.test { "edge":"14" }
  es.error.cause { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }

여기서 알 수 있는 점은 기준선 타겟이 프로젝트의 도구 모음에 의해 애플리케이션이 변환되는 방식에 큰 영향을 미칠 수 있다는 것입니다. 이 예의 애플리케이션은 매우 기본적인 것으로, React나 애플리케이션 자체에 최첨단 개발자 환경 기능이 많지 않습니다. 훨씬 더 복잡한 애플리케이션의 경우 선택한 기준 타겟을 준수하기 위해 추가된 폴리필, 변환, 기타 추가 코드 소스 등 훨씬 다른 결과가 나올 수 있습니다.

5. browserslist-config-baseline을 사용하여 다운스트림 브라우저 타겟팅

검토를 위해 Baseline이 타겟팅하는 핵심 브라우저 세트에는 다음 브라우저가 포함됩니다.

  • Chrome
  • Android용 Chrome
  • Firefox
  • Android 기반 Firefox
  • Edge
  • macOS의 Safari
  • iOS의 Safari

하지만 '다운스트림 브라우저'라고 하는 브라우저는 타겟팅할 수 있습니다. 이러한 브라우저는 엔진이 핵심 브라우저 세트의 브라우저(대부분 Chromium)에서 파생된 브라우저입니다. 여기에는 Opera, Samsung Internet 등의 브라우저가 포함됩니다. 다음과 같이 package.json 파일에서 browserslist-config-baseline가 타겟팅하도록 구성할 수 있습니다.

"browserslist": "extends browserslist-config-baseline/with-downstream"

이는 널리 사용 가능한 기준 타겟에 따라 다운스트림 브라우저를 타겟팅합니다. 이 쿼리가 Browserslist 쿼리로 어떻게 변환되는지 확인하려면 프로젝트를 다시 빌드하세요.

npm start

그런 다음 Browserslist 쿼리의 변경사항을 확인합니다.

Using targets: {
  "android": "108",
  "chrome": "108",
  "edge": "108",
  "firefox": "108",
  "ios": "16",
  "opera": "94",
  "opera_mobile": "80",
  "safari": "16",
  "samsung": "21"
}

연도별로 다운스트림 브라우저를 타겟팅할 수도 있습니다. 예를 들면 다음과 같습니다.

"browserslist": "extends browserslist-config-baseline/with-downstream/2016"

이 구성을 사용하면 Browserslist 쿼리가 다음과 같이 변경됩니다.

Using targets: {
  "android": "53",
  "chrome": "53",
  "edge": "14",
  "firefox": "49",
  "ios": "10",
  "opera": "40",
  "opera_mobile": "80",
  "safari": "10",
  "samsung": "6.2"
}

6. 린터 및 기타 도구

browserslist-config-baseline는 번들러와 도구 모음의 다른 부분에 유용한 도구이지만, 구성의 일부로 기준 타겟을 채택한 린터와 같은 다른 도구에도 가치가 있습니다.

기준선에 대한 린터 지원의 좋은 예로는 CSS 린팅의 일부로 @eslint/css를 사용하여 기준선 신규, 기준선 광범위하게 사용 가능 또는 기준선 연도를 타겟팅할 수 있는 use-baseline 규칙을 제공하는 ESLint가 있습니다. 커뮤니티 @html-eslint/eslint-plugin 패키지에도 유사한 규칙이 있어 eslint.config.js 파일의 HTML 기능에 대해 동일한 작업을 할 수 있습니다.

export default [
  /* Omitted JS linting rules ... */
  // Lint CSS files for Baseline:
  {
    files: ["**/*.css"],
    plugins: {
      css
    },
    language: "css/css",
    rules: {
      "css/no-duplicate-imports": "error",
      // Lint CSS files to make sure they are using
      // only Baseline Widely available features:
      "css/use-baseline": ["warn", {
        available: "widely"
      }]
    },
  },
  // Lint HTML and JSX files for Baseline:
  {
    files: ["**/*.html"],
    ...html.configs["flat/recommended"],
    rules: {
      // Lint HTML files to make sure they are using
      // only Baseline Widely available features:
      "@html-eslint/use-baseline": ["warn", {
        available: "widely"
      }]
    }
  }
];

이 구성에서 몇 가지 유의해야 할 사항이 있습니다.

  1. HTML 및 CSS 린팅 패키지는 모두 use-baseline 규칙을 사용하며 available: "widely" 구성 옵션을 사용하여 널리 사용 가능하도록 설정됩니다.
  2. 두 린트 패키지 모두 린터 위반의 로그 수준이 "warn"로 설정됩니다. 빌드가 발생하지 않도록 오류 코드를 사용하여 종료되도록 "error"로 설정할 수 있습니다.

이전에 npm run build를 실행할 때 린터 출력을 확인했을 수도 있지만 린터 출력만 확인하려면 다음을 실행하면 됩니다.

npm run lint

표시되는 출력은 프로젝트의 CSS에서 여러 경고를 강조 표시합니다.

/var/www/baseline-demos/tooling/webpack-browserslist-config-baseline/src/css/normalize.css
  222:3  warning  Property 'outline' is not a widely available baseline feature  css/use-baseline

/var/www/baseline-demos/tooling/webpack-browserslist-config-baseline/src/css/styles.css
  62:3   warning  Property 'outline' is not a widely available baseline feature                                css/use-baseline
  81:23  warning  Value 'subgrid' of property 'grid-template-rows' is not a widely available baseline feature  css/use-baseline

7. 요약

보시다시피 프로젝트에서 browserslist-config-baseline를 사용하려면 기본 빌드 도구와 Browserslist를 어느 정도 이해해야 하지만, 프로젝트에 배치하는 작업은 약간의 노력으로 가능합니다. 이 기능을 사용하면 버전 번호 측면에서 지원하는 브라우저를 더 이상 생각할 필요가 없으며, 대신 Baseline 타겟이 모든 작업을 처리해 줍니다.

또한 Rollup에서 실행되는 이 데모 버전이 있으며 이 Codelab은 해당 데모를 사용하여 대부분 따라 할 수 있습니다.

기준선 지원은 다른 번들링 도구에서도 나타나기 시작했습니다. 예를 들어 내부적으로 Rollup을 사용하는 Vite는 이제 버전 7부터 널리 사용 가능한 Baseline 브라우저를 기본적으로 타겟팅합니다.

어떤 방법을 선택하든 프로젝트의 도구 모음에 browserslist-config-baseline를 도입하고 자신에게 맞는 기준 타겟을 선택하면 더 간단하고 안정적인 방식으로 브라우저를 타겟팅할 수 있습니다.