StyleX 디코딩: Meta&#의 최첨단 스타일링 시스템

Susan Sarandon
풀어 주다: 2024-11-10 21:32:02
원래의
734명이 탐색했습니다.

매년 10월 인도 고아에서 최대 규모의 국제 리액트 컨퍼런스가 열립니다. 네, 저는 React India에 대해 이야기하고 있습니다. 올해(2024년)는 이 멋진 컨퍼런스에서 연설할 기회를 얻었기 때문에 저에게 더욱 특별했습니다. 라이브로 시청하지 못하셨다면 제 강연을 녹음해 보세요. 비디오를 보는 것보다 읽는 것을 더 좋아한다면 이 블로그가 바로 당신을 위한 것입니다! 자세히 살펴보겠습니다.

스타일X란 무엇인가요?

StyleX는 현재 Facebook, Instagram, WhatsApp과 같은 플랫폼의 기본 시스템으로 사용되는 Meta의 새로운 확장 가능한 스타일 라이브러리입니다. 특히 대규모 React 애플리케이션에서 CSS-in-JS 접근 방식으로 경험한 문제점을 해결합니다. StyleX는 원자 CSS와 정적 CSS의 최고의 기능을 혼합한 하이브리드 솔루션을 제공함으로써 효율적이고 모듈식이며 확장 가능한 대안을 제공합니다.

Meta는 StyleX를 어떻게, 왜 만들었나요?

  • Meta는 대규모 프로젝트에서 기존 CSS-in-JS 라이브러리에서 직면하는 특정 문제를 해결하기 위해 StyleX를 구축했습니다.
  1. 사용되지 않는 스타일: 프로젝트가 성장함에 따라 CSS는 종종 사용되지 않는 규칙을 축적하여 스타일시트를 부풀립니다.
  2. 성능 문제: CSS-in-JS 솔루션은 특히 애플리케이션과 함께 번들로 제공되는 경우 대용량 CSS 파일이나 성능 병목 현상을 초래할 수 있습니다.
  3. CSS-in-JS 라이브러리 크기: JavaScript 스타일 지정에 사용되는 많은 인기 라이브러리는 번들에 불필요한 무게를 추가하여 로드 시간에 영향을 미칩니다.
  • StyleX 소개: 2019년 Facebook UI 개편의 일환으로 만들어졌으며 2023년 12월에 오픈소스로 공개되었습니다.
  • CSS 최적화: StyleX를 사용하기 전에는 Facebook의 단일 페이지에 약 15-45MB의 CSS 스타일이 로드되었습니다. 단일 CSS 번들을 활용하여 StyleX를 사용하면 이 용량이 약 200~300KB로 대폭 줄었습니다.
  • StyleX의 목적: 스타일링의 복잡성을 대규모로 효과적으로 관리하기 위해 개발되었습니다. 이는 수많은 개발자가 수천 개의 구성 요소를 만들 때 발생하는 문제를 해결하며, 이는 종종 CSS 내에서 특정성 충돌로 이어집니다. StyleX는 스타일링을 위한 구조화된 프레임워크를 제공함으로써 스타일링 과정에서 일관성과 명확성을 유지하는 데 도움이 됩니다.
  • 원자 클래스 생성: StyleX는 처음부터 지속적으로 원자 클래스를 생성하여 유지 관리 효율성을 높이고 스타일 충돌을 줄이기 위해 구성 요소당 여러 클래스 이름을 갖는 절충안을 수용합니다.

StyleX의 주요 기능:

  1. 원자적 CSS 생성: StyleX는 원자적 CSS 생성을 사용합니다. 즉, 각 스타일 규칙에 대해 작고 재사용 가능한 클래스를 생성합니다. 이 접근 방식은 최종 CSS 번들의 중복을 최소화할 뿐만 아니라 스타일시트의 전체 크기를 줄여 성능을 향상시킵니다.

  2. CSS 중복 제거: StyleX는 각 스타일에 대해 고유한 클래스 식별자를 생성하여 중복된 스타일을 효과적으로 제거합니다. 이 중복 제거 프로세스를 통해 각 속성-값 쌍이 한 번만 렌더링되어 더욱 간결한 CSS 출력에 기여합니다.

  3. “마지막 스타일을 적용한 것이 항상 승리합니다!”: StyleX는 마지막으로 적용한 스타일이 우선하는 예측 가능한 스타일링 규칙을 따릅니다. 이 기능은 스타일 규칙 충돌에 대한 우려를 완화하므로 디버깅을 단순화하고 개발자의 자신감을 높여줍니다.

  4. React에 최적화: React 애플리케이션용으로 특별히 설계된 StyleX는 React 생태계에 완벽하게 통합됩니다. 이를 통해 개발자는 구성 요소 내에서 직접 스타일을 정의하여 더욱 응집력 있는 개발 워크플로를 조성할 수 있습니다.

  5. Flow 및 TypeScript 지원: StyleX는 "Flow"(Meta에서 생성)로 작성되었으며 TypeScript에 대한 강력한 지원을 제공하여 스타일과 테마에 대한 유형 안전 API를 활성화합니다. 이러한 유형의 안전성은 코드 신뢰성과 유지 관리성을 향상시켜 복잡한 스타일링 시나리오를 더 쉽게 관리할 수 있게 해줍니다.

  6. 유연한 조건부 스타일링: StyleX를 사용하면 개발자는 구성 요소 상태나 소품에 따라 조건부로 스타일을 적용할 수 있습니다. 이러한 유연성을 통해 사용자 상호 작용이나 애플리케이션 상태 변화에 맞춰 동적인 스타일을 적용할 수 있습니다.

  7. 범위 스타일링: StyleX의 범위 스타일링 기능은 스타일이 의도된 구성 요소에만 적용되도록 보장합니다. 이를 통해 대규모 코드베이스에서 자주 발생하는 의도하지 않은 부작용과 특이성 문제를 방지할 수 있습니다.

  8. 런타임 계산 감소: StyleX는 컴파일 타임에 모든 스타일을 정적 CSS 파일에 묶어 런타임 계산을 최소화합니다. 이러한 최적화를 통해 특히 대규모 애플리케이션에서 렌더링 시간이 빨라지고 성능이 향상됩니다.

  9. 더 나은 코드 유지 관리: StyleX는 스타일을 해당 구성 요소와 함께 배치하고 원자 클래스를 활용하여 더 나은 코드 유지 관리를 촉진합니다. 개발자는 광범위한 스타일시트를 일일이 살펴보지 않고도 스타일을 쉽게 이해하고 수정할 수 있습니다.

  10. 최소 CSS 출력: 원자 CSS를 사용하면 CSS 출력이 최소화되어 특히 성능에 도움이 됩니다. 프로젝트의 규모와 복잡성이 증가함에 따라 StyleX는 기능 저하 없이 CSS 번들을 관리 가능한 상태로 유지합니다.

  11. 모든 규모의 프로젝트에 적합: StyleX는 모든 규모의 프로젝트에 적합하지만 대규모 애플리케이션에서도 탁월한 성능을 발휘합니다. 그 아키텍처는 성능이나 유지 관리 가능성을 저하시키지 않으면서 광범위한 스타일링 요구 사항의 복잡성을 처리하도록 설계되었습니다.

어떻게 작동하는지 볼까요?‍?

이 기사의 코드 예제는 React로 작성되었으며 주로 App.jsx와 Button.jsx라는 두 가지 구성 요소를 사용하여 작업합니다. 스타일을 추가하기 전에 이러한 구성요소의 기본 구조를 살펴보겠습니다.

import Button from "./components/Button";

const App = () => {
  return (
    <div>
      <h1>StyleX by Meta</h1>
      <Button text="Get Started" />
    </div>
  );
};

export default App;
로그인 후 복사
로그인 후 복사
// Button.jsx
import PropTypes from "prop-types";

const Button = ({ text }) => {
  return <button>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

Decoding StyleX: Meta

StyleX를 사용하여 스타일 추가

import PropTypes from "prop-types";
import * as stylex from "@stylexjs/stylex";

const styles = stylex.create({
  base: {
    fontSize: 18,
    backgroundColor: "black",
    color: "white",
  },
});

const Button = ({ text }) => {
  return <button {...stylex.props(styles.base)}>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

이러한 스타일을 사용하려면 styleX 패키지에서 가져온 다음 개체를 매개변수로 사용하는 stylex.create 메서드를 사용하여 스타일을 정의해야 합니다. 그런 다음 stylex.props 메소드를 사용하여 구성요소에 스타일을 적용할 수 있습니다.

이 예에서 base는 적용하려는 스타일의 이름입니다. StyleX에서는 이를 네임스페이스라고 부릅니다. 이것이 현재 버튼 구성요소의 모습입니다.

Decoding StyleX: Meta

의사 클래스에 스타일 추가

import PropTypes from "prop-types";
import * as stylex from "@stylexjs/stylex";

const styles = stylex.create({
  base: {
    fontSize: 18,
    backgroundColor: {
      default: "black",
      ":hover": "blue",
    },
    color: "white",
  },
});

const Button = ({ text }) => {
  return <button {...stylex.props(styles.base)}>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

StyleX를 사용하면 의사 클래스에 스타일을 추가하는 것이 매우 간단합니다. 이전 예에서 backgroundColor는 문자열이었습니다. 여기서는 이를 기본값과 의사 클래스를 갖는 객체로 변환합니다.

Decoding StyleX: Meta

미디어 쿼리 작업

import PropTypes from "prop-types";
import * as stylex from "@stylexjs/stylex";

const styles = stylex.create({
  base: {
    fontSize: 18,
    backgroundColor: {
      default: "black",
      ":hover": "blue",
    },
    color: "white",
    width: {
      default: "100px",
      "@media (max-width: 476px)": "100%",
    },
  },
});

const Button = ({ text }) => {
  return <button {...stylex.props(styles.base)}>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

StyleX가 다른 스타일링 라이브러리와 다르게 하는 한 가지 기능은 미디어 쿼리입니다. 여기서는 요구 사항에 따라 모든 네임스페이스에 미디어 쿼리를 적용합니다. 이 예에서는 큰 화면의 경우 버튼 너비를 100픽셀로, 작은 화면이나 모바일 장치의 경우 100% 너비로 정의합니다.

Decoding StyleX: Meta

"마지막으로 적용된 스타일이 항상 승리"하는 방법을 살펴보겠습니다.

이전 예를 확장하여 이 버튼의 다양한 변형을 만드는 방법을 살펴보겠습니다.

const styles = stylex.create({
  base: {
    fontSize: 18,
    backgroundColor: {
      default: "teal",
      ":hover": "blue",
    },
    color: "white",
    width: {
      default: "100px",
      "@media (max-width: 476px)": "100%",
    },
  },
  highlighted: {
    backgroundColor: "orange",
  },
  danger: {
    backgroundColor: "red",
  },
  primary: {
    backgroundColor: "green",
  },
});

const Button = ({ text, isHighlighted, variant }) => {
  return (
    <button
      {...stylex.props(
        styles.base,
        isHighlighted && styles.highlighted, // conditional styling
        styles[variant]
      )}
    >
      {text}
    </button>
  );
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
  isHighlighted: PropTypes.bool,
  variant: PropTypes.oneOf(["danger", "primary"]),
};
로그인 후 복사

stylex.create 메소드에 네임스페이스를 몇 개 더 추가하고 다양한 배경색을 제공해 보겠습니다. 또한 Button 구성 요소 내에서 2개의 새로운 prop을 허용합니다. isHighlighted는 강조 표시된 네임스페이스를 적용하는 데 사용하는 부울 소품입니다. 그리고 변형은 기본, 위험 또는 강조 표시된 네임스페이스를 적용하는 데 사용하는 소품입니다.

// App.jsx
import Button from "./components/Button";

const App = () => {
  return (
    <div>
      <h1>StyleX by Meta</h1>
      <div {...stylex.props(styles.main)}>
        <Button text="Base Button" />
        <Button text="Highlighted Button" isHighlighted />
        <Button text="Danger Button" isHighlighted variant="danger" />
        <Button text="Primary Button" variant="primary" />
      </div>
    </div>
  );
};

export default App;
로그인 후 복사

다른 props가 전달되는 Button 구성 요소의 복사본을 몇 개 더 만듭니다. 이것이 지금 우리 앱의 모습입니다.

Decoding StyleX: Meta

이제 '위험버튼'을 자세히 살펴보겠습니다. isHighlighted를 true로 전달했더라도 강조 표시된 네임스페이스는 적용되지 않습니다. 위험 변형은 마지막에 언급되었으므로 적용됩니다. 따라서 버튼의 배경색은 빨간색이 됩니다.

상위 스타일 재정의

App.jsx에서 이 Button 구성 요소의 스타일 속성을 직접 재정의할 수 있습니다.

import Button from "./components/Button";

const App = () => {
  return (
    <div>
      <h1>StyleX by Meta</h1>
      <Button text="Get Started" />
    </div>
  );
};

export default App;
로그인 후 복사
로그인 후 복사

Decoding StyleX: Meta

이 예에서 재정의 네임스페이스는 현재 모든 속성을 허용합니다. 그러나 StyleX는 재정의할 수 있는 속성을 제한하는 기능을 제공합니다. 이 기능은 TypeScript를 사용할 때 특히 유용합니다.

// Button.jsx
import PropTypes from "prop-types";

const Button = ({ text }) => {
  return <button>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

이 제한으로 인해 backgroundColor 및 색상 속성만 재정의될 수 있습니다.

원자 클래스는 어떻게 작동합니까(내부)

Decoding StyleX: Meta

이전 예제 코드까지 위로 스크롤하면 3가지 다른 네임스페이스(App.jsx의 기본, Button.jsx의 강조 표시 및 기본)에 margin: "1rem" 스타일을 추가한 것을 볼 수 있습니다. Devtools를 사용하여 요소를 검사하면 다양한 구성 요소(기본 컨테이너, 강조 표시된 버튼 및 기본 버튼)가 동일한 클래스 이름으로 연결되어 있고 margin: "1rem" 스타일을 유지하는 x42y017 클래스가 1개만 있음을 알 수 있습니다.

이렇게 StyleX는 원자 클래스를 사용하여 번들 크기를 크게 줄였습니다. 특정 임계값에 도달한 후에는 새 클래스가 생성되지 않습니다. 대신 기존 클래스를 재사용합니다.

전역 변수 및 테마

세부적인 수준에서 스타일을 재정의할 수 있다는 점은 훌륭합니다! 그러나 특정 디자인 시스템은 디자인 토큰과 테마를 지원해야 합니다. 이것이 바로 StyleX가 등장하는 곳입니다. StyleX의 테마 API 디자인은 React의 Context API에서 직접 영감을 받았습니다. 변수는 React 컨텍스트가 생성되는 방식과 유사한 기본값으로 정의되며, UI 하위 트리에 대해 이러한 변수에 대해 서로 다른 값을 "제공"하기 위해 테마를 생성할 수 있습니다.

x.stylex.js 파일을 생성하여 전역 스타일을 생성할 수 있습니다. 이 명명 규칙을 따르십시오. 이 파일에서는 아래와 같이 stylex.defineVars를 사용합니다.

import PropTypes from "prop-types";
import * as stylex from "@stylexjs/stylex";

const styles = stylex.create({
  base: {
    fontSize: 18,
    backgroundColor: "black",
    color: "white",
  },
});

const Button = ({ text }) => {
  return <button {...stylex.props(styles.base)}>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

사용자가 선호하는 테마를 참고하여 상수값인 DARK로 설정하고 있습니다. 그리고 이 colors 변수를 이용하여 새로운 테마를 만들어 보겠습니다.

import PropTypes from "prop-types";
import * as stylex from "@stylexjs/stylex";

const styles = stylex.create({
  base: {
    fontSize: 18,
    backgroundColor: {
      default: "black",
      ":hover": "blue",
    },
    color: "white",
  },
});

const Button = ({ text }) => {
  return <button {...stylex.props(styles.base)}>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

한번 테마를 생성하면 StyleX의 다른 스타일과 동일하게 사용할 수 있습니다.

import PropTypes from "prop-types";
import * as stylex from "@stylexjs/stylex";

const styles = stylex.create({
  base: {
    fontSize: 18,
    backgroundColor: {
      default: "black",
      ":hover": "blue",
    },
    color: "white",
    width: {
      default: "100px",
      "@media (max-width: 476px)": "100%",
    },
  },
});

const Button = ({ text }) => {
  return <button {...stylex.props(styles.base)}>{text}</button>;
};

Button.propTypes = {
  text: PropTypes.string.isRequired,
};

export default Button;
로그인 후 복사
로그인 후 복사

이렇게 myCustomTheme을 사용하여 밝은 모드와 어두운 모드에서 각각 동일한 페이지를 볼 수 있습니다.

Decoding StyleX: Meta

그거 포장이야?

만세! StyleX 작업의 요지를 성공적으로 얻었습니다. 이 글을 읽어주셔서 감사합니다. StyleX가 무엇인지, Meta는 어떻게 만들었고, 어떻게 사용하는지에 대한 좋은 이해가 되었기를 바랍니다. 의견 섹션이나 Twitter에서 여러분의 생각/질문을 공유해 주세요. 이 블로그가 흥미로우셨다면 이 게시물에 좋아요(좋아하는 이모티콘과 함께?)를 눌러주시면 감사하겠습니다.

평화 ✌

참고자료

  • 내 세션 소개
  • 여기서 제 강연을 시청해 보세요!
  • 나에게 React India는 어땠나요?

면접 준비를 위해 Topmate에서 저와 소통하세요
Decoding StyleX: Meta

위 내용은 StyleX 디코딩: Meta&#의 최첨단 스타일링 시스템의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿