Skip to content

[Feature Request] less + css modules > styled-components 的自动化工具 #10526

@txp1035

Description

@txp1035

Background

为了使用styled-components做的转换工具。 @sorrycc
这块的具体业务背景是要帮助bigfish的巨石项目做升级吗?

Proposal

我找了下没找到现成的工具。
所以还是主要还是通过Babel来识别和处理文件。

主要流程是:

  1. 收集数据。收集数据先遍历组件,有导入less的存起来第一层对象,再遍历less文件,第二层对象,如果less中有导入less类推。最后得到所有有用的less文件。这里主要是给组件找对应关系的less。也可以检测出用户有哪儿些less是没有使用废弃的,可以提示给用户
  2. 处理数据,逻辑在扩展里,欢迎补充。处理数据主要处理了常见的用法,不常见的提示给用户。
  3. 写入数据
  4. 删除无用文件。

我还有个想法是能不能通过快照来验证,可以肯定是类名是不一样的,但是其他应该是一样的?。

Additional context

为所有全局样式表设置一个全局样式

搜集

  1. 每个less文件中找:global
  2. src下的less文件

处理

统一处理成一个文件放到src下。
在src下面有个styled-components.ts文件来放

export const GlobalStyle = createGlobalStyle`
  ......
`

下面这段我理解应该是umi内置处理了。

import { createGlobalStyle } from 'styled-components'

export const GlobalStyle = createGlobalStyle`
  ......
`

const Layout = ({ children, title }) => (
  <>
    <GlobalStyle />
    <Header />
    <Page />
    </Footer>
  </>
)

将所有变量移动到主题样式中

before

@theme-text: #cccccc;
@label-theme: #2d5a6b;
@label-text: @theme-text;
@label-border: 1px solid @theme-text;

after
变量定义不能用-符号需要处理。这一块也可以放在styled-components.ts里。通过import { ThemeProvider } from 'styled-components'透传到后面的样式中。

const color: '#442d6b';
const theme_text = '#cccccc';
const label_theme = '#2d5a6b';
const label_text = theme_text;
const label_border = `1px solid ${theme_text}`;


const theme = {
  color, //I don't need color: color here because the names are the same
  "theme-text": theme_text,
  "label-theme": label_theme,
  "label-text": label_text,
  "label-border": label_border
}

export default theme;

实际有变量转后样子

const BlogItem = styled.div`
  ${({theme})=> `
    color: theme['color'];
  `}
`

这个引入工作也可以umi吃掉

import { ThemeProvider } from 'styled-components'
import {theme} from './styled-components' //This is the theme object that we defined above

const Layout = ({ children, title }) => (
  <>
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <Header />
      <Page />
      </Footer>
    </ThemeProvider>
  </>
)

注意有计算的形式处理

before

@global-border-radius: 12px;

.blogItem {
  border-radius: @global-border-radius / 2;
}

after

export const modifySize = (fontString, modifyFrac) => {
  const fontNumber = parseFloat(fontString)
  const fontUnit = fontString.replace(/[0-9]/g, '')
  return `${fontNumber * modifyFrac}${fontUnit}`
}

const BlogItem = styled.div`
  ${({theme})=> `
    border-radius: `${modifySize(theme['global-border-radius'], 2)}`
  `}
`

将 less 组件分解为样式块

替换组件内带classname的节点基于classname生成节点名字

before

.blogItem {
  font-size: 12px;
  margin-top: 24px;
  //..many more stylings excluded
}
export const Pages = props => <div {...xxx} className={styles.blogItem}>...<div/>

after

export const StyledBlogItem = styled.div`
  font-size: 12px;
  margin-top: 24px;
  //...many more stylings excluded
`

export const Pages = props => <StyledBlogItem {...xxx}>....<StyledBlogItem/>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions