326 - 《手写 styled-components》

发布于 2023年7月26日

之前排查一个问题时把 styled-components 的源码大概翻了一遍,想着既然时间已经花了,就再多花点写个 toy version 记录下吧。

目标是支持最简的 styled-components 使用场景,如下。1)可以用 Tagged Template Literals 声明样式,2)支持 CSS 嵌套语法。

import React from 'react';
import { styled } from '../libs/styled-components';

const Wrapper = styled.div`
  font-size: 12px;
  h1 {
    color: blue;
  }
`;

export default function Page() {
  return (
    <Wrapper>
      <h1>Page index</h1>
    </Wrapper>
  );
}

toy-styled-components 代码如下。

import React from "react";
import * as stylis from "stylis";

function normalizeCSS(css, selector) {
  const compiled = stylis.compile(`${selector} {${css}}`);
  return stylis.serialize(compiled, stylis.stringify);
}

function insertRules(id, rules) {
  const style = document.createElement("style");
  style.id = id;
  document.head.appendChild(style);
  style.innerHTML = rules;
  return style;
}

class ComponentStyle {
  constructor(rules, componentId) {
    this.rules = rules;
    this.componentId = componentId;
  }
  generateAndInjectStyles() {
    const name = this.componentId;
    const css = this.rules.join("");
    insertRules(name, normalizeCSS(css, `.${name}`));
    return name;
  }
}

function useInjectedStyle(componentStyle

内容预览已结束

此内容需要会员权限。请先登录以查看完整内容。