Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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

Open
txp1035 opened this issue Feb 15, 2023 · 1 comment
Open

Comments

@txp1035
Copy link
Member

txp1035 commented Feb 15, 2023

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/>
@txp1035 txp1035 changed the title [Feature Request] say something [Feature Request] less + css modules > styled-components 的自动化工具 Feb 15, 2023
@sorrycc
Copy link
Member

sorrycc commented Feb 17, 2023

1、业务背景不止是巨石应用,也包括普通尺寸的应用,所以希望这个方案是通用的。
2、global 的这样处理感觉并不好,他在组件样式里用,我觉得是希望局部覆盖样式,而不是加全局样式,为了简单,可以先「遇到 :global 时不处理并给警告」,我们解 80% 的场景就够了,剩下 20% 可以让用户手动改
3、感觉应该从简单开始做,我们先完成这个场景的转换吧。

foo.css

.normal {
  color: red;
  .foo { color: green; }
}

foo.tsx

import styles from './foo.css';
export function Foo() {
  return (
    <div className={styles.normal}>
      <h1>title</h1>
      <h2 className={styles.foo}>foo</h2>
    </div>
  );
}

应该转化成这种,

import { styled } from 'umi';
import styles from './foo.css';

const FooWrapper = styled.div`
  .normal {
    color: red;
    .foo { color: green; }
  }
`;

export function Foo() {
  return (
    <FooWrapper>
      <h1>title</h1>
      <h2 className="foo">foo</h2>
    </FooWrapper>
  );
}

4、然后再考虑变量和 global 之类的场景

@sorrycc sorrycc mentioned this issue Feb 23, 2023
68 tasks
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants