简体   繁体   English

在React与CSS-loader和Webpack中使用字符串类名称

[英]Using string class names in React with css-loader and Webpack

I was following a few tutorials on how to set up internal sass/scss/css support for React in Webpack. 我正在关注一些有关如何在Webpack中为React设置内部sass / scss / css支持的教程。 I finally got something I'm happy with, using HtmlWebpackPlugin to generate the index.html based on a template, sass-loader , typings-for-css-modules-loader (a css-loader wrapper to deal with css modules in typescript), and MiniCssExtractPlugin , to create a separate css file in my built dist folder. 我终于得到了令我满意的东西,使用HtmlWebpackPlugin基于模板, sass-loadertypings-for-css-modules-loader (用于处理HtmlWebpackPlugin typings-for-css-modules-loadercss-loader包装器)来生成index.htmlMiniCssExtractPlugin ,以在我构建的dist文件夹中创建一个单独的css文件。 My configuration works like this: 我的配置如下所示:

module: {
  rules: [

    ...

    { test: /\.(sa|sc|c)ss?$/,
      use: [
        {
          loader: MiniCssExtractPlugin.loader,
          options: {}
        },
        {
          loader: 'typings-for-css-modules-loader',
          options: {
            modules: true,
            namedExport: true,
            camelCase: true
          }
        },
        'sass-loader'
      ]
    }
  ]
}

This setup works when I'm importing my css classes in my React components as objects: 当我将React组件中的CSS类作为对象导入时,此设置有效:

hello.css

.foo {
    color: #5df7ff;
}

hello.tsx

import * as React from 'react';

import { foo } from './hello.css';

export interface HelloProps {
  compiler: string;
  framework: string;
}

export const Hello = (props: HelloProps) =>
  <h1 className={foo}>Hello: {props.compiler} and {props.framework}!!!</h1>; // This works: text is colored correctly

The problem arises when I want to use string class names in the React component, as such (same css as before): 当我想在React组件中使用字符串类名称时,就会出现问题(与之前的CSS相同):

hello.tsx

import * as React from 'react';

import './hello.css';

export interface HelloProps {
  compiler: string;
  framework: string;
}

export const Hello = (props: HelloProps) =>
  <h1 className="foo">Hello: {props.compiler} and {props.framework}!!!</h1>; // This does not work: text is not colored

I assume this is because the Webpack loaders aren't 'smart' enough to correctly resolve the string class names in the React DOM: the loaders do not map the string class names to the hashed ones produced by css-loader. 我认为这是因为Webpack加载器不够“智能”,无法正确解析React DOM中的字符串类名称:这些加载器没有将字符串类名称映射到css-loader生成的哈希名称。

I understand that using string css class names in React is not the idiomatic way to include css classes: ideally you would have one single complete css class per component using css modules which you would import as in the first example. 我知道在React中使用字符串css类名称不是包括css类的惯用方式:理想情况下,每个组件使用css模块将有一个完整的css类,您可以像第一个示例中那样导入。

The problem arises however when using external UI component libraries (eg Ant Design, Semantic UI) which seem to reference their own css string classes. 但是,当使用外部UI组件库(例如Ant Design,Semantic UI)时,似乎会引用其自己的CSS字符串类,因此会出现问题。

This puts me off using these external libraries. 这使我无法使用这些外部库。

Example from using antd (Ant Design): 使用antd (Ant Design):

anthello.tsx

import React from 'react';
import Button from 'antd/lib/button';
import 'antd/es/button/style/index.css';

export interface HelloAntProps {
  message: string;
}

export const HelloAnt = ({ message }: HelloAntProps ) => {
  return (
    <div>
      <h1>Hello {message}</h1>
      <Button type="primary">Test</Button>
    </div>
  );
};

generated css file using the loader stack: 使用加载程序堆栈生成的css文件:

._3WAJv754FZTMKDXGocE913 { /* This class corresponds to the Ant Design ant-btn class */
  line-height: 1.5;
  display: inline-block;
  font-weight: 400;
  text-align: center;
  ...

and the css classes which are looked for in the actual DOM: 以及在实际DOM中寻找的css类:

<button type="button" class="ant-btn ant-btn-primary"><span>Test</span></button> 
<!-- This does not work, as the only classes present in the css are the hashed ones generated by css-loader -->

I wouldn't know how else to import these libraries and pack them using Webpack into a single css bundle without getting this to work. 我不知道其他如何导入这些库并使用Webpack将它们打包到单个css捆绑包中,而又无法正常工作。

Am I missing something? 我想念什么吗?

tl;dr tl; dr

Is there any way to get css class strings to be correctly resolved with css-loader in the React DOM via some Webpack loader? 有什么方法可以通过一些Webpack加载器使CSS类字符串在React DOM中使用css-loader正确解析吗? Is there any workaround I'm missing? 我有什么解决方法吗?

Update: managed to work around the issue by disabling the 'css-modules' options in my css-loader . 更新:通过禁用css-loader的'css-modules'选项设法解决了该问题。

The hashing of the css class names is due to the css-modules option. CSS类名称的哈希归因于css-modules选项。 By disabling this option, the class names are not hashed anymore, enabling external libraries to reference their own classes directly. 通过禁用此选项,不再对类名进行哈希处理,从而使外部库可以直接引用其自身的类。

It doesn't look like the issue can be solved easily by keeping the css-modules option. 通过保留css-modules选项,似乎无法轻松解决该问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM