在样式化组件中使用 Ant 设计变量

IT技术 javascript reactjs less gatsby styled-components
2021-05-07 11:04:34

GatsbyJS站点Ant DesignStyled Components结合使用我希望能够访问样式组件中的 Ant Design 变量(用Less编写)。像这样的东西:

const StyledButton = styled(Button)`
  background-color: @primary-color
`

我做了一些研究,发现了两个可能有帮助的库,但我不知道如何让它们工作(至少不是在 Gatsby 环境中)。这些是图书馆:

Styless包有一个示例,说明如何让 Less 变量在 Styled Compoments 中工作:https : //github.com/jean343/styless/blob/master/examples/Theme.js

但是,我一直无法让该示例在我的 Gatsby 站点上运行——无论我是否尝试在我的基本布局组件、ingatsby-ssr.jsgatsby-browser.js.

所以,我想知道 - 有没有办法能够访问 GatsbyJS 站点中样式组件内的 Less 变量(使用这些库或不使用这些库)?如果是这样,如何?

谢谢。

2个回答

如果你只盯着获得在样式化组件的Antd变量名,你可以转而使用import的选项styless这要简单得多,而且不需要解析任何变量。

在您的 中.babelrc,使用此代码导入样式。

{
    "plugins": [
        [
            "styless",
            {
                "import": "~antd/lib/style/themes/default.less",
                "lessOptions": {
                    "javascriptEnabled": true
                }
            }
        ]
    ]
}

然后,所有客户端代码都可以简化为:

import React from "react"
import { Button } from 'antd';
import styled from "styled-components"
import "antd/dist/antd.css";

const StyledButton = styled( Button )`
  background-color: @primary-color;
`;

export default () => {
    return <StyledButton>button</StyledButton>
}

不要忘记删除.cache要产生效果文件夹。

当您使用 Gatsby 时,您可以使用加载器,在这种情况下,您可以获得变量名 "less-vars-loader!antd/lib/style/themes/default.less"

这对于没有变量的简单的 less 工作表可以很好地工作,但是这对于 Antd 来说效果不佳,因为它们设置了一个变量@primary-color: @blue-6;

import React from "react"
import { Button } from 'antd';
import styled, { ThemeProvider } from "styled-components"
import Layout from "../components/layout"
import DefaultTheme from "less-vars-loader!antd/lib/style/themes/default.less"
import "antd/dist/antd.css";

const StyledButton = styled( Button )`
  background-color: @primary-color;
`;

const App = () => (
    <Layout>
        <StyledButton>Hi people</StyledButton>
    </Layout>
);
console.log( "DefaultTheme", DefaultTheme["primary-color"] ); // Here, this shows @blue-6
DefaultTheme["primary-color"] = "blue"; // For demo purpose, setting the value here.

export default () => (
    <ThemeProvider theme={DefaultTheme}><App/></ThemeProvider>
);

正如所Promise的,我正在添加我的示例 webpack 加载器来解析 antd 变量。它确实解析了大约 600 个变量,但它仍然以"JavaScript evaluation error: 'ReferenceError: colorPalette is not defined'". 这对于不需要javascriptEnabled.

const less = require( "less" );
const varRgx = /^[@$]/;

module.exports = async source => {
    const resolveVariables = async () => {
        const root = await new Promise( resolve => {
            const parseOpts = {
                javascriptEnabled: true,
                paths: ["node_modules/antd/lib/style/themes/"],
            };
            less.parse( source, parseOpts, ( e, root, imports, options ) => {
                if( e ){
                    console.error( `LESSLoader - Error compiling`, e );
                }
                resolve( root );
            } );
        } );
        if( !root ) return;

        const evalEnv = new less.contexts.Eval();
        evalEnv.frames = [root];
        evalEnv.javascriptEnabled = true;

        const ret = {};
        for( let [name, variable] of Object.entries( root.variables() ) ){
            ret[name.replace( varRgx, "" )] = variable.value.eval( evalEnv ).toCSS();
        }
        return ret;
    };

    return `module.exports = ${JSON.stringify( await resolveVariables() )};`;
};

这可以用 调用import DefaultTheme from "./LESSLoader!antd/lib/style/themes/default.less"