如何在反应库包中内联/包含 css

问题描述

我正在尝试构建一个可在其他应用程序中使用的 React 组件库,但我遇到了使用组件库打包 css/less 的问题。

在组件库包中:

component.tsx

import React,{ ReactElement } from 'react';
import styles from "./component.less";

const TestComponent: React.FC  = (): ReactElement => {
    ....

    return (
        <div className={styles.root}>
            ....
        </div>
    );
};

export default TestComponent;

component.less

@bg-color: #428bca;

.root {
    background-color: @bg-color;
}

我运行以下命令来构建库:

> tsc --emitDeclarationOnly
> lessc src/component.less dist/library.css
> babel src --out-dir dist --extensions .ts,.tsx --source-maps
> copyfiles -u 1 src/**/*.less dist/

并在 dist 目录中获取

> index.d.ts
> index.js
> library.css
> component.less
> ....

在不同的应用程序中,我只安装库并使用组件:

import TestComponent from "library-package";

<TestComponent /> // in the render somewhere

当我启动这个应用程序时,组件被渲染,但 css/less 代码没有被应用,也没有被导入。

我想在库包中包含一些认的 css。而且我知道我可以只在应用程序的 library.css 中包含 index.tsx 并且 css 可以工作,但我不希望其他应用程序必须包含一个 css 文件或具有较少的loader 来处理 css,如果它不使用 less 本身。

我认为当前的问题是应用程序不知道如何处理库中的 .less 文件,因为它没有更少的加载程序设置(尽管我没有收到任何错误)

tldr:应用程序只需安装组件库,将组件包含在渲染中,组件将使用一些 css 进行渲染(最好在库中使用 less)。可以这样做吗?

解决方法

我想我正在寻找类似 styled-components 的东西,但使用 less + minifying 而不是在 JavaScript 文件中编写 CSS 并包装 HTML 标签。

使用 styled-components 库,我让它以这种方式工作:

component.tsx

import React,{ ReactElement } from "react";
import cssesc from "cssesc";
import styled,{ ThemeProvider,DefaultTheme  } from "styled-components";

export interface TestComponentTheme extends DefaultTheme {
    backgroundColor?: string;
}

const DEFAULT_THEME: TestComponentTheme = {
    backgroundColor: "#428bca",};

const StyledDiv = styled.div`
    background-color: ${props => cssesc(props.theme.backgroundColor)};
`;

interface TestComponentInput {
    theme?: TestComponentTheme;
}

const TestComponent: React.FC<TestComponentInput> = ({theme}: TestComponentInput ): ReactElement => {
    ....

    let componentTheme: TestComponentTheme = Object.assign({},DEFAULT_THEME);

    if (theme) {
        componentTheme= Object.assign({},componentTheme,theme);
    }

    return (
        <ThemeProvider theme={componentTheme}>
            <StyledDiv>
                ....
            </StyledDiv>
        </ThemeProvider>
    );
};

export default TestComponent;

构建库现在只需要两个步骤:

> tsc --emitDeclarationOnly
> babel src --out-dir dist --extensions .ts,.tsx --source-maps

并且 dist 目录中不再有 CSS 文件:

> index.d.ts
> index.js
> ....

在不同的应用程序中,我只安装库并使用组件(使用 CSS 内联呈现):

import TestComponent from "library-package";

<TestComponent /> // in the render somewhere

并且我可以选择覆盖组件的 CSS:

import TestComponent,{ TestComponentTheme } from "library-package";

const customTheme: TestComponentTheme = {
    backgroundColor: "#000fff",};

<TestComponent theme={customTheme} /> // in the render somewhere