Hướng dẫn css-in-js vs css modules performance - hiệu suất mô-đun css-in-js so với css

Trong sự phát triển phía trước hiện đại, đặc biệt là trong React, ở mức độ thấp hơn trong VUE, đây là nhiều cách khác nhau để viết CSS cho các thành phần của chúng tôi.

Trong bài viết này tôi sẽ không so sánh song song, tôi sẽ nhấn mạnh cả hai tính năng và vấn đề thú vị của các giải pháp cụ thể mà tôi được hướng dẫn trong tình huống tôi ở vị trí của một người xác định "kiến trúc CSS" của một dự án.

SASS (CSS, CSS-Proprocessors)

SASS (hơn nữa chỉ là CSS) rất dễ học nhưng rất khó để duy trì. Nó có nghĩa là gì?

Vấn đề chính của CSS thuần túy, anh ta không giải quyết vấn đề cách ly kiểu cho mỗi thành phần. Và tất cả các phong cách của bạn sẽ rò rỉ vào các thành phần khác, và điều này sẽ tạo ra rất nhiều vấn đề trong các dự án lớn. Vâng, vấn đề này cũng lâu đời như thế giới và chúng ta có những cách khác nhau để giải quyết vấn đề này:
Yeah, this problem is as old as the world, and we have different ways to solve this problem:

  • Phương pháp BEM
  • Bem kết hợp với thiết kế nguyên tử
  • Các giải pháp khác như CSS nguyên tử, SMACSS, v.v.

Nhưng tất cả các giải pháp này chỉ là một phép đo lường, điều này không loại bỏ sự cần thiết của nhà phát triển, và điều này có nghĩa là chúng ta vẫn có một vấn đề như một sự bất đồng của con người tầm thường.metodologies, this does not remove the need for the developer to think, and this means that we still have such a problem as a banal human inattention.

Và vấn đề thứ hai, bởi vì tất cả các phong cách của chúng tôi chỉ là CSS toàn cầu trừu tượng, chúng tôi không có hỗ trợ TypeScript để kiểm tra xem phong cách của chúng tôi có thực sự tồn tại không. Và vấn đề kết quả mà chúng ta không có trí thông minh IDE tốt (đặc biệt nếu chúng ta có

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
8 nhập một số tệp có chứa vars và mixin, trong cấu hình webpack/vite). Vâng, chúng tôi có các giải pháp như:
Yeah, we have solutions like:

  • SCSS IntelliSense để tự động hoàn thành cho các biến SASS/SCSS của chúng tôi
  • SCSS ở mọi nơi để tự động hoàn thành cho các lớp của chúng tôi trong các tệp JSX/TSX.

Nhưng đây chỉ là các plugin cho IDE và sẽ không thể tích hợp chúng vào đường ống CI/CD của bạn để kiểm tra xem chúng tôi có sử dụng các lớp CSS không tồn tại không.

Mô -đun CSS

Và trong thời điểm này để giải quyết tất cả các vấn đề về việc có CSS ​​toàn cầu bước vào các mô -đun CSS giai đoạn.

Về cơ bản

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
9. Các mô -đun CSS Nó giống như cấu trúc mã CSS và tất cả. Sự khác biệt chính là các phương thức gọi là quá khác nhau.
CSS Modules it is the same as the CSS code structure and all. The main difference is calling methods is too different.

Các mô -đun CSS cung cấp một số mô -đun JS biểu diễn những gì chứa các liên kết đến các lớp CSS. Và tên lớp của chúng tôi sẽ trông giống như

import { css } from 'styled-components'

// Works only on the client-side
// For SSR we need have some Context to Provide User-Agent from request context to React application context
const USER_AGENT = window.navigator.userAgent;

// More details about browser detect regex
// here - https://github.com/ua-parser/uap-core/blob/master/regexes.yaml
export const checkIsIE10OrOlder = /MSIE /g.test(USER_AGENT);
export const checkIsIE11 = /Trident\//g.test(USER_AGENT);
export const checkIsEdge = /Edge\//g.test(USER_AGENT);
export const checkIsFireFox = /Firefox\//gi.test(USER_AGENT);
export const checkIsChrome = /Chrome\//gi.test(USER_AGENT);
export const checkIsSafari = /Safari\//gi.test(USER_AGENT);
export const checkIsYandex = /YaBrowser\//gi.test(USER_AGENT);

export const styleIE11Browser = (...args) => checkIsIE11 ? css(...args) : null;
export const styleEdgeBrowser = (...args) => checkIsEdge ? css(...args) : null;
export const styleMicrosoftBrowsers = (...args) => checkIsIE11 || checkIsEdge || checkIsIE10OrOlder ? css(...args) : null;
export const styleIsNotMicrosoftBrowsers = (...args) => !checkIsIE11 && !checkIsIE10OrOlder ? css(...args) : null;
export const styleFireFoxBrowser = (...args) => checkIsFireFox ? css(...args) : null;
export const styleSafariBrowser = (...args) => checkIsSafari ? css(...args) : null;
export const styleYandexBrowser = (...args) => checkIsYandex ? css(...args) : null;

export const browser = {
    ie: styleMicrosoftBrowsers,
    ie11: styleIE11Browser,
    edge: styleEdgeBrowser,
    notIE: styleIsNotMicrosoftBrowsers,
    firefox: styleFireFoxBrowser,
    moz: styleFireFoxBrowser,
    safari: styleSafariBrowser,
    yandex: styleYandexBrowser,
};
0 và bộ chọn lớp của chúng tôi dưới mui xe sẽ được chuyển đổi thành một cái gì đó như
import { css } from 'styled-components'

// Works only on the client-side
// For SSR we need have some Context to Provide User-Agent from request context to React application context
const USER_AGENT = window.navigator.userAgent;

// More details about browser detect regex
// here - https://github.com/ua-parser/uap-core/blob/master/regexes.yaml
export const checkIsIE10OrOlder = /MSIE /g.test(USER_AGENT);
export const checkIsIE11 = /Trident\//g.test(USER_AGENT);
export const checkIsEdge = /Edge\//g.test(USER_AGENT);
export const checkIsFireFox = /Firefox\//gi.test(USER_AGENT);
export const checkIsChrome = /Chrome\//gi.test(USER_AGENT);
export const checkIsSafari = /Safari\//gi.test(USER_AGENT);
export const checkIsYandex = /YaBrowser\//gi.test(USER_AGENT);

export const styleIE11Browser = (...args) => checkIsIE11 ? css(...args) : null;
export const styleEdgeBrowser = (...args) => checkIsEdge ? css(...args) : null;
export const styleMicrosoftBrowsers = (...args) => checkIsIE11 || checkIsEdge || checkIsIE10OrOlder ? css(...args) : null;
export const styleIsNotMicrosoftBrowsers = (...args) => !checkIsIE11 && !checkIsIE10OrOlder ? css(...args) : null;
export const styleFireFoxBrowser = (...args) => checkIsFireFox ? css(...args) : null;
export const styleSafariBrowser = (...args) => checkIsSafari ? css(...args) : null;
export const styleYandexBrowser = (...args) => checkIsYandex ? css(...args) : null;

export const browser = {
    ie: styleMicrosoftBrowsers,
    ie11: styleIE11Browser,
    edge: styleEdgeBrowser,
    notIE: styleIsNotMicrosoftBrowsers,
    firefox: styleFireFoxBrowser,
    moz: styleFireFoxBrowser,
    safari: styleSafariBrowser,
    yandex: styleYandexBrowser,
};
1 (chi tiết ở đây), sẽ giải quyết vấn đề cô lập của lớp CSS.

Nhưng, những gì về hỗ trợ TypeScript? Và ở đây chúng tôi có một số giải pháp:
And here we have some solutions:

  • TypeScript plugin Mô -đun CSS, đó là plugin cung cấp thông tin dịch vụ ngôn ngữ TypeScript về các bộ chọn lớp có chứa tệp mô -đun CSS đã nhập. Nhưng đối với VSCode, chúng tôi cần thiết lập TypeScript LS để sử dụng phiên bản không gian làm việc. Để biết thêm thông tin, hãy đến đây hoặc ở đây.

Đó là giải quyết vấn đề bằng cách sử dụng tên lớp không tồn tại cho các tệp TS/TSX, nhưng nếu chúng ta sử dụng các tệp Vue và

import { css } from 'styled-components'

// Works only on the client-side
// For SSR we need have some Context to Provide User-Agent from request context to React application context
const USER_AGENT = window.navigator.userAgent;

// More details about browser detect regex
// here - https://github.com/ua-parser/uap-core/blob/master/regexes.yaml
export const checkIsIE10OrOlder = /MSIE /g.test(USER_AGENT);
export const checkIsIE11 = /Trident\//g.test(USER_AGENT);
export const checkIsEdge = /Edge\//g.test(USER_AGENT);
export const checkIsFireFox = /Firefox\//gi.test(USER_AGENT);
export const checkIsChrome = /Chrome\//gi.test(USER_AGENT);
export const checkIsSafari = /Safari\//gi.test(USER_AGENT);
export const checkIsYandex = /YaBrowser\//gi.test(USER_AGENT);

export const styleIE11Browser = (...args) => checkIsIE11 ? css(...args) : null;
export const styleEdgeBrowser = (...args) => checkIsEdge ? css(...args) : null;
export const styleMicrosoftBrowsers = (...args) => checkIsIE11 || checkIsEdge || checkIsIE10OrOlder ? css(...args) : null;
export const styleIsNotMicrosoftBrowsers = (...args) => !checkIsIE11 && !checkIsIE10OrOlder ? css(...args) : null;
export const styleFireFoxBrowser = (...args) => checkIsFireFox ? css(...args) : null;
export const styleSafariBrowser = (...args) => checkIsSafari ? css(...args) : null;
export const styleYandexBrowser = (...args) => checkIsYandex ? css(...args) : null;

export const browser = {
    ie: styleMicrosoftBrowsers,
    ie11: styleIE11Browser,
    edge: styleEdgeBrowser,
    notIE: styleIsNotMicrosoftBrowsers,
    firefox: styleFireFoxBrowser,
    moz: styleFireFoxBrowser,
    safari: styleSafariBrowser,
    yandex: styleYandexBrowser,
};
2? Ở đây chúng tôi có vấn đề, vì Volar chẳng hạn không cung cấp hỗ trợ cho các mô -đun CSS plugin TypeScript, để biết thêm thông tin ở đây. Và bước vào giai đoạn:
Here we have problem, because volar for example does not provide support of TypeScript plugin CSS Modules, for more information go here.
And there enters the stage:

  • Vite Plugin SASS DTS sẽ tạo ra các khai báo TypeScript cho các mô -đun CSS của chúng tôi.
  • Hoặc cho webpack CSS mô -đun tải TypeScrip

Và chúng tôi đã kiểm tra loại cho dự án Vue🥳

Và những gì về sự tự động hoàn thành IDE cho các vars SCSS/SASS, mixin? Mọi thứ đều giống nhau ở đây, chỉ SCSS IntelliSense
Everything is the same here, only SCSS IntelliSense

Nhưng CSS không có ngôn ngữ phong phú. Làm thế nào chúng ta có thể thêm sự linh hoạt hơn nữa và cải thiện trải nghiệm phát triển của phong cách viết?

CSS-in-JS

Ngoài ra, vì chúng tôi viết JS, chúng tôi có thể viết các chức năng trợ giúp cho các đoạn CSS của chúng tôi, những gì sẽ được hỗ trợ đầy đủ, điều đó có nghĩa là làm giảm đáng kể số lượng lỗi và nhận được trí tuệ IDE.

Ví dụ cơ bản, nó là một truy vấn phương tiện và các biến JS để theo chủ đề.

export const screenSizes = {
  mobile: 767,
  tablet: 1023,
  computer: 1440,
  desktop: 1920,
} as const

export const makeMedia = (from: null | number, to?: null | number) => `@media screen${
  from
    ? ` and (min-width: ${from}px)`
    : ''}${
  to
    ? ` and (max-width: ${to - 1}px)`
    : ''}`

export const media = {
  mobile: makeMedia(null, screenSizes.mobile),
  tablet: makeMedia(null, screenSizes.tablet),
  computer: makeMedia(null, screenSizes.computer),
  desktop: makeMedia(null, screenSizes.desktop),
  largescreen: makeMedia(screenSizes.desktop),
  tabletOnly: makeMedia(screenSizes.mobile, screenSizes.tablet),
  computerOnly: makeMedia(screenSizes.tablet, screenSizes.computer),
  desktopOnly: makeMedia(screenSizes.computer, screenSizes.desktop),
  aboveMobile: makeMedia(screenSizes.mobile),
  aboveTablet: makeMedia(screenSizes.tablet),
  aboveComputer: makeMedia(screenSizes.computer),
  aboveDesktop: makeMedia(screenSizes.desktop),
}

export const color = {
  primary: '#FF6B38',
  primaryOpacity27: 'rgba(255, 107, 56, .27)',
  primaryOpacity35: 'rgba(255, 107, 56, .35)',
  primaryLighten: '#F5F5F5',
  primaryLighten2: '#FDA38A',
  blackOpacity80: 'rgba(0, 0, 0, .8)',
  blackOpacity60: 'rgba(0, 0, 0, .6)',
  blackLight: '#161616',
  blackLightOpacity42: 'rgba(22, 22, 22, .42)',

  backgroundGray: '#161616',
  backgroundGrayLight: '#969696',
} as const

Nhập chế độ FullScreenen EXIT Mode FullScreen

Ví dụ sử dụng:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`

Nhập chế độ FullScreenen EXIT Mode FullScreen

Ví dụ sử dụng:

import { css } from 'styled-components'

// Works only on the client-side
// For SSR we need have some Context to Provide User-Agent from request context to React application context
const USER_AGENT = window.navigator.userAgent;

// More details about browser detect regex
// here - https://github.com/ua-parser/uap-core/blob/master/regexes.yaml
export const checkIsIE10OrOlder = /MSIE /g.test(USER_AGENT);
export const checkIsIE11 = /Trident\//g.test(USER_AGENT);
export const checkIsEdge = /Edge\//g.test(USER_AGENT);
export const checkIsFireFox = /Firefox\//gi.test(USER_AGENT);
export const checkIsChrome = /Chrome\//gi.test(USER_AGENT);
export const checkIsSafari = /Safari\//gi.test(USER_AGENT);
export const checkIsYandex = /YaBrowser\//gi.test(USER_AGENT);

export const styleIE11Browser = (...args) => checkIsIE11 ? css(...args) : null;
export const styleEdgeBrowser = (...args) => checkIsEdge ? css(...args) : null;
export const styleMicrosoftBrowsers = (...args) => checkIsIE11 || checkIsEdge || checkIsIE10OrOlder ? css(...args) : null;
export const styleIsNotMicrosoftBrowsers = (...args) => !checkIsIE11 && !checkIsIE10OrOlder ? css(...args) : null;
export const styleFireFoxBrowser = (...args) => checkIsFireFox ? css(...args) : null;
export const styleSafariBrowser = (...args) => checkIsSafari ? css(...args) : null;
export const styleYandexBrowser = (...args) => checkIsYandex ? css(...args) : null;

export const browser = {
    ie: styleMicrosoftBrowsers,
    ie11: styleIE11Browser,
    edge: styleEdgeBrowser,
    notIE: styleIsNotMicrosoftBrowsers,
    firefox: styleFireFoxBrowser,
    moz: styleFireFoxBrowser,
    safari: styleSafariBrowser,
    yandex: styleYandexBrowser,
};

Nhập chế độ FullScreenen EXIT Mode FullScreen

Ví dụ sử dụng:

// Works with both client-side and server-side rendering
export const isIECssDetect = (...args) => css`@media all and (-ms-high-contrast:none) {${css(...args)}}`;
export const isFireFoxCssDetect = (...args) => css`@-moz-document url-prefix() {${css(...args)}}`;

export const browser = {
    css: {
        ie: isIECssDetect,
        firefox: isFireFoxCssDetect,
        moz: isFireFoxCssDetect,
    },
};

Nhập chế độ FullScreenen EXIT Mode FullScreen

Ví dụ sử dụng:

import styled from 'styled-components'
import { browser } from 'ui/theme'

export const StyledBackground = styled.img`
    position: absolute;
    object-fit: contain;
    object-position: right;
    top: 0;
    left: 0;
    z-index: -2;
    width: 100%;
    height: 100%;

    ${browser.ie`
        width: auto;
        right: 0;
        left: auto;
    `}
`;

Nhập chế độ FullScreenen EXIT Mode FullScreen

Ví dụ sử dụng:
And in this very helpful will be ability to create small helper components like:

import styled, { css } from 'styled-components'

interface LayoutProps {
    flow: 'column' | 'row' | 'column-reverse'
    wrap?: 'wrap' | 'nowrap'
    padding?: string
    margin?: string
    justify?: 'center' | 'flex-start' | 'flex-end' | 'space-between' | 'space-around' | 'stretch'
    align?: 'center' | 'flex-start' | 'flex-end' | 'space-between' | 'space-around' | 'stretch'
    width?: string
    height?: string
    shrink?: string
    'data-name'?: string
    grow?: string
}

export const Layout = styled.div<LayoutProps>`
  display: flex;
  flex-direction: ${p => p.flow};
  flex-wrap: ${p => p.wrap};
  padding: ${p => `${p.padding}`};
  margin: ${p => `${p.margin}`};
  ${p => p.width && css`
    width: ${p.width}
  `};
  ${p => p.height && css`
    height: ${p.height};
  `};
  ${p => p.justify && css`
    justify-content: ${p.justify}
  `};
  ${p => p.align && css`
    align-items: ${p.align}
  `};

  ${p => p.shrink && css`
    & > * + * {
      flex-shrink: ${p.shrink};
    }
  `};
  ${p => p.grow && css`
    flex-grow: ${p.grow};
  `};
`

Layout.defaultProps = {
    wrap: 'nowrap',
    padding: '0',
    margin: '0',
    justify: undefined,
    align: undefined,
    width: '',
    height: '',
    shrink: undefined,
    'data-name': 'layout',
    grow: '',
}

Nhập chế độ FullScreenen EXIT Mode FullScreen

Ví dụ sử dụng:

import { Layout } from 'ui/atoms'
import { SeparateTitle } from 'ui/molecules'
import { StyledWrapper } from './style'

const OrderResponseForm: FC<Props> = () => {
    // Some code

    return (
        <Layout flow="column" wrap="wrap" margin="40px 0 0">
            <SeparateTitle line={false}>
                {i18n.t('ORDER_DETAILS_FORM_TITLE')}
            </SeparateTitle>
            <StyledWrapper
                flow="row"
                padding="24px 30px 20px 24px"
            >
                {`* Some more JSX *`}
            </StyledWrapper>
        </Layout>
    )
}

Nhập chế độ FullScreenen EXIT Mode FullScreen

Trong style.ts bạn có khả năng mở rộng thành phần bố cục với việc lưu kiểm tra loại đạo cụ
With saving props Type checking

export const StyledWrapper = styled(Layout)`
    border-radius: 36px;
    box-shadow: 0 4px 20px ${color.shadowBlack2};

    ${media.tablet} {
        padding: 24px;
        margin-bottom: 8px;
    }
`

Nhập chế độ FullScreenen EXIT Mode FullScreen

Hoặc chúng ta cũng có thể tạo thành phần có thể tái sử dụng cho văn bản:

import styled, { css } from 'styled-components'
import {
    color as colors,
    selectWeight,
    WeightType,
} from 'ui/theme'

interface TextProps {
    align?: string
    size?: string
    color?: keyof typeof colors
    weight?: WeightType
    lineHeight?: string
    whiteSpace?: 'pre-wrap' | 'initial' | 'pre' | 'nowrap' | 'pre-line' | 'normal'
    letterSpacing?: string
    transform?: string
    'data-name'?: string
    decoration?: string
}

export const Text = styled.span<TextProps>`
    line-height: ${p => p.lineHeight};
    font-size: ${({ size }) => size};
    color: ${({ color = 'text' }) => colors[color] ? colors[color] : color};
    letter-spacing: ${({ letterSpacing }) => letterSpacing};
    text-align: ${({ align }) => align};
    text-decoration: ${({ decoration }) => decoration};
    font-weight: ${({ weight = 'normal' }) => selectWeight(weight).weight};
    white-space: ${p => p.whiteSpace};

    ${({ transform }) => transform && css`
        text-transform: ${transform};
    `}
`

Text.defaultProps = {
    align: 'initial',
    size: '14px',
    color: 'text',
    weight: 'normal',
    lineHeight: 'normal',
    whiteSpace: 'initial',
    letterSpacing: 'initial',
    decoration: 'initial',
    'data-name': 'text',
}

Nhập chế độ FullScreenen EXIT Mode FullScreen

Hoặc chúng ta cũng có thể tạo thành phần có thể tái sử dụng cho văn bản:

const StyledPrecheckInner = styled(Layout).attrs<Props>(() => ({
    flow: 'column',
    width: '100%',
}))`
    max-width: 378px;
    margin: 0 auto;

    > ${Text} {
        margin: 8px 0;
    }
`

Nhập chế độ FullScreenen EXIT Mode FullScreen

Hoặc chúng ta cũng có thể tạo thành phần có thể tái sử dụng cho văn bản:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
0

Nhập chế độ FullScreenen EXIT Mode FullScreen

Hoặc chúng ta cũng có thể tạo thành phần có thể tái sử dụng cho văn bản:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
1

Nhập chế độ FullScreenen EXIT Mode FullScreen

Hoặc chúng ta cũng có thể tạo thành phần có thể tái sử dụng cho văn bản:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
2

Nhập chế độ FullScreenen EXIT Mode FullScreen

Hoặc chúng ta cũng có thể tạo thành phần có thể tái sử dụng cho văn bản:

CSS-in-JS tăng lên một trải nghiệm phát triển cấp độ mới (DX), bởi vì giải quyết vấn đề cô lập các kiểu và mang lại một số tính năng thú vị như xác định không phải trong JSX của chúng tôi, mà theo biến số Tuyên bố, có vẻ như:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
3

Nhập chế độ FullScreenen EXIT Mode FullScreen

Hoặc một trường hợp cụ thể hơn:
You just need some JavaScript processor like Babel, ESBuild, SWC, and etc.

Và nó là hỗ trợ các đạo cụ động (nhiều ví dụ hơn ở trên):

Nhưng ... JS sẽ cung cấp cho chúng tôi nhiều sức mạnh hơn và chúng tôi có thể thực hiện một số biến đổi CSS thời gian chạy điên rồ:

Và tất cả đều là hỗ trợ TypeScript ...
Everything is not as bad as it sounds, styled-components for example very fast even for large projects, if you use styled-components for just static isolated styles for some element, but when use start to use too many dynamic props in reusable components it is will very fast and very noticeable slow down your application 😔

Và trong trường hợp SRR CSS trong JS cung cấp cho chúng tôi khả năng tạo ra "CSS quan trọng" sẽ tạo ra CSS những gì chỉ cần cho trang này, để tối ưu hóa thời gian trình duyệt mà phân tích CSS của chúng tôi:

Và không khó để kết bạn với Bundler của chúng tôi, bất kể chúng tôi sử dụng Webpack, Vite hay Rollup, v.v., bạn chỉ cần một số bộ xử lý JavaScript như Babel, Esbuild, SWC, v.v.

Nghe có vẻ thực sự tuyệt vời!

  • Nhưng trước tiên, các kiểu CSS-in-JS chỉ được tạo ra nếu thành phần trên màn hình, trong khi các giải pháp dựa trên CSS hoặc các CSS khác được bao gồm trong CSS tách biệt (không xem xét các kiểu trong thẻ kiểu), nó được cung cấp cho chúng tôi khả năng lưu trữ CSS của chúng tôi các tập tin.
  • Và thứ hai ... Thế hệ CSS của các lực lượng hoạt động của JavaScript không miễn phí và điều này sẽ ăn thời gian chạy của chúng tôi 😢 mọi thứ không tệ như âm thanh, ví dụ như các thành phần kiểu dáng rất nhanh đối với các dự án lớn, nếu bạn sử dụng kiểu dáng -Components cho các kiểu bị cô lập tĩnh cho một số yếu tố, nhưng khi sử dụng bắt đầu sử dụng quá nhiều đạo cụ động trong các thành phần có thể tái sử dụng, nó sẽ rất nhanh và rất đáng chú ý làm chậm ứng dụng của bạn 😔
  • Và họ đi trên giai đoạn biên dịch CSS trong các giải pháp JS (hoặc không chạy CSS trong JS)

Biên dịch thời gian CSS-in-JS (không chạy CSS-in-JS)

Tôi sẽ chỉ ra một vài người chơi:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
4

Nhập chế độ FullScreenen EXIT Mode FullScreen

Linaria (Phổ biến nhất, Hỗ trợ phản ứng và Svelte)
More details here or Linaria docs provide guide about how it implement manually

Trích xuất vani (rất thú vị, hỗ trợ nhiều người hơn Linaria)
And your style utils output is more like classes composition:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
5

Nhập chế độ FullScreenen EXIT Mode FullScreen

Được biên dịch (biên dịch Giải pháp CSS-IN-JS từ Atlassian)

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
6

Nhập chế độ FullScreenen EXIT Mode FullScreen

Tôi điều từ tên "Biên dịch thời gian" mà bạn hiểu, cách viết CSS-in-JS, nhưng không có hoặc không có chi phí thời gian chạy rất nhỏ.

Ví dụ, Linaria có các tính năng của các thành phần tương tự, như các thành phần có đạo cụ động:

// Component style.ts file
import styled from 'styled-components'
import { media, color } from 'ui/theme'

export const StyledWrapper = styled.div`
    position: relative;
    z-index: 1;

    background-color: ${color.white};
    border-radius: 36px;
    box-shadow: 0 10px 20px ${color.shadowPrimary2};
`

export const StyledTopGutter = styled.div`
    padding: 46px 46px 24px;

    display: flex;
    flex-flow: column wrap;

    ${media.mobile} {
        padding: 24px;
    }
`
7

Nhập chế độ FullScreenen EXIT Mode FullScreen

Sự khác biệt chính mà dưới Hood Linaria tạo ra một thành phần trình bao bọc mà cho các kiểu động sẽ sử dụng các biến CSS, nó tăng tốc đáng kể các đạo cụ động. Thông tin chi tiết ở đây hoặc tài liệu Linaria cung cấp hướng dẫn về cách nó thực hiện thủ công

Nhưng bước tổng hợp mang lại cho chúng tôi một số hạn chế, như

import { css } from 'styled-components'

// Works only on the client-side
// For SSR we need have some Context to Provide User-Agent from request context to React application context
const USER_AGENT = window.navigator.userAgent;

// More details about browser detect regex
// here - https://github.com/ua-parser/uap-core/blob/master/regexes.yaml
export const checkIsIE10OrOlder = /MSIE /g.test(USER_AGENT);
export const checkIsIE11 = /Trident\//g.test(USER_AGENT);
export const checkIsEdge = /Edge\//g.test(USER_AGENT);
export const checkIsFireFox = /Firefox\//gi.test(USER_AGENT);
export const checkIsChrome = /Chrome\//gi.test(USER_AGENT);
export const checkIsSafari = /Safari\//gi.test(USER_AGENT);
export const checkIsYandex = /YaBrowser\//gi.test(USER_AGENT);

export const styleIE11Browser = (...args) => checkIsIE11 ? css(...args) : null;
export const styleEdgeBrowser = (...args) => checkIsEdge ? css(...args) : null;
export const styleMicrosoftBrowsers = (...args) => checkIsIE11 || checkIsEdge || checkIsIE10OrOlder ? css(...args) : null;
export const styleIsNotMicrosoftBrowsers = (...args) => !checkIsIE11 && !checkIsIE10OrOlder ? css(...args) : null;
export const styleFireFoxBrowser = (...args) => checkIsFireFox ? css(...args) : null;
export const styleSafariBrowser = (...args) => checkIsSafari ? css(...args) : null;
export const styleYandexBrowser = (...args) => checkIsYandex ? css(...args) : null;

export const browser = {
    ie: styleMicrosoftBrowsers,
    ie11: styleIE11Browser,
    edge: styleEdgeBrowser,
    notIE: styleIsNotMicrosoftBrowsers,
    firefox: styleFireFoxBrowser,
    moz: styleFireFoxBrowser,
    safari: styleSafariBrowser,
    yandex: styleYandexBrowser,
};
4 FN rất điên rồ, nó giống như lớp phạm vi CSS. Và đầu ra sử dụng phong cách của bạn giống như thành phần của lớp:

Và vì bạn viết JavaScript, bạn cũng có thể sử dụng các chức năng tiện ích, nhưng bước tổng hợp mang lại cho chúng tôi một số hạn chế. Ví dụ: tôi thích sử dụng nhập khẩu tuyệt đối, nhưng đôi khi Linaria không thể nhập tệp 'UI/chủ đề' của mình và để giải quyết vấn đề này, chúng tôi cần sử dụng Babel-plugin-import-resolver.

Nhưng đó không phải là tất cả, trước khi bạn sẽ bắt đầu sử dụng Linaria, bạn cần phải định cấu hình Bundler của mình 😄

Nhưng tôi ngưỡng mộ rằng mọi người cố gắng tạo ra các giải pháp thậm chí như CSS thời gian biên dịch nguyên tử, đây là một ý tưởng kỹ thuật tuyệt vời 🤯

Sự kết luận

Cách tiếp cận nào để chọn để viết phong cách ứng dụng?

Tôi nghĩ rằng tất cả phụ thuộc vào loại ứng dụng chúng tôi đang viết. Mỗi cách tiếp cận có chỗ dựa và nhược điểm riêng. Của tôi về điều này:
Each approaches has its own prop and cons.
My throughs on this:

  • CSS-in-JS-Chọn khi bạn không có ứng dụng quan trọng hoàn hảo với thiết kế tùy chỉnh. Ví dụ, chúng tôi có nhiều ứng dụng "backoffice" những gì nhân viên công ty sử dụng nội bộ. CSS-in-JS trong trường hợp này sẽ cung cấp API thanh lịch và linh hoạt sẽ tối đa khả năng đọc mã, tăng năng suất của nhà phát triển và trải nghiệm định kỳ.
  • Mô -đun CSS - Chọn khi bạn có một số ứng dụng quan trọng. Ví dụ: bạn đang phát triển một tài khoản cá nhân của một khách hàng ngân hàng được sử dụng bởi hàng triệu người dùng. Hoặc chỉ là thương mại điện tử 😝

Là CSS

Mặc dù tải các bảng kiểu bên ngoài lớn có thể tác động tiêu cực đến các số liệu hiệu suất, CSS đơn giản nhanh hơn để các trình duyệt kết xuất so với kiểu dáng được tạo bằng mã. CSS tĩnh có đường cong học tập nhẹ nhàng hơn các thư viện CSS-in-JS với độ phức tạp ít hơn.simple CSS is faster for browsers to render than styling that is generated using code. Static CSS has a gentler learning curve than CSS-in-JS libraries with less complexity.

Là CSS

Việc triển khai CSS-in-JS theo kiểu dường như mất khoảng 50% thời gian để kết xuất so với phiên bản không có kiểu.Mặc dù trong nhiều trường hợp, chi phí hiệu suất liên quan đến CSS-in-JS hầu như không được cảm nhận, trong các trường hợp khác (ví dụ: có các cây thành phần lớn), nó có thể trở nên không thể bỏ qua.. While in many occasions, the performance cost related to CSS-in-JS is hardly perceived, in other cases (for instance featuring large component trees), it may become impossible to neglect.

Tại sao CSS

CSS-in-JS tạo ra vấn đề gì?Một trong những điểm đau lớn hơn của CSS-in-JS là bản thân mã bắt đầu trông giống JavaScript hơn.Điều này có thể khó vượt qua nếu nhóm của bạn có đầy đủ các nhà phát triển CSS hoặc SASS, những người không thoải mái khi viết JavaScript.the code itself starts to look more like JavaScript. This can be hard to overcome if your team is full of CSS or Sass developers who are uncomfortable writing JavaScript.

Các mô -đun CSS có tốt hơn không?

Các mô -đun CSS cho phép bạn viết các kiểu trong các tệp CSS nhưng tiêu thụ chúng dưới dạng các đối tượng JavaScript để xử lý và an toàn bổ sung.Các mô -đun CSS rất phổ biến vì chúng tự động làm cho tên lớp và hoạt hình trở nên độc đáo để bạn không phải lo lắng về va chạm tên chọn.CSS Modules are very popular because they automatically make class and animation names unique so you don't have to worry about selector name collisions.