在带有 css-loader 和 Webpack 的 React 中使用字符串 class 名称
Using string class names in React with css-loader and Webpack
我正在学习一些关于如何在 Webpack 中设置对 React 的内部 sass/scss/css 支持的教程。我终于得到了我满意的东西,使用 HtmlWebpackPlugin
基于模板生成 index.html
,sass-loader
,typings-for-css-modules-loader
(一个 css-loader
包装器来处理使用打字稿中的 css 模块)和 MiniCssExtractPlugin
,在我构建的 dist
文件夹中创建一个单独的 css 文件。我的配置是这样的:
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'
]
}
]
}
当我将我的 css classes 作为对象导入我的 React 组件时,此设置有效:
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
当我想在 React 组件中使用字符串 class 名称时,问题就出现了(与之前相同 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
我认为这是因为 Webpack 加载器 'smart' 不足以正确解析 React DOM 中的字符串 class 名称:加载器不映射字符串 class 名称到 css-loader.
生成的散列名称
我知道在 React 中使用字符串 css class 名称并不是包含 css classes 的惯用方式:理想情况下你应该有一个完整的 css class 每个组件使用 css 模块,您将在第一个示例中导入这些模块。
然而,当使用外部 UI 组件库(例如 Ant Design、Semantic UI)似乎引用了它们自己的 css 字符串 class 时,问题就出现了。
这让我无法使用这些外部库。
使用 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>
);
};
使用加载器堆栈生成了 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;
...
和 css classes 是在实际 DOM:
中寻找的
<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 -->
我不知道如何导入这些库并使用 Webpack 将它们打包到一个 css 包中而不让它工作。
我是不是漏掉了什么?
tl;dr
有什么方法可以通过某些 Webpack 加载程序在 React DOM 中使用 css-loader
正确解析 css class 字符串?我是否缺少任何解决方法?
更新:通过禁用我的 css-loader
中的 'css-modules' 选项设法解决了这个问题。
css class 名称的散列是由于 css-modules
选项。通过禁用此选项,class 名称不再被散列,使外部库能够直接引用它们自己的 classes。
看起来问题并不能通过保留 css-modules
选项轻松解决。
我正在学习一些关于如何在 Webpack 中设置对 React 的内部 sass/scss/css 支持的教程。我终于得到了我满意的东西,使用 HtmlWebpackPlugin
基于模板生成 index.html
,sass-loader
,typings-for-css-modules-loader
(一个 css-loader
包装器来处理使用打字稿中的 css 模块)和 MiniCssExtractPlugin
,在我构建的 dist
文件夹中创建一个单独的 css 文件。我的配置是这样的:
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'
]
}
]
}
当我将我的 css classes 作为对象导入我的 React 组件时,此设置有效:
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
当我想在 React 组件中使用字符串 class 名称时,问题就出现了(与之前相同 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
我认为这是因为 Webpack 加载器 'smart' 不足以正确解析 React DOM 中的字符串 class 名称:加载器不映射字符串 class 名称到 css-loader.
生成的散列名称我知道在 React 中使用字符串 css class 名称并不是包含 css classes 的惯用方式:理想情况下你应该有一个完整的 css class 每个组件使用 css 模块,您将在第一个示例中导入这些模块。
然而,当使用外部 UI 组件库(例如 Ant Design、Semantic UI)似乎引用了它们自己的 css 字符串 class 时,问题就出现了。
这让我无法使用这些外部库。
使用 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>
);
};
使用加载器堆栈生成了 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;
...
和 css classes 是在实际 DOM:
中寻找的<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 -->
我不知道如何导入这些库并使用 Webpack 将它们打包到一个 css 包中而不让它工作。
我是不是漏掉了什么?
tl;dr
有什么方法可以通过某些 Webpack 加载程序在 React DOM 中使用 css-loader
正确解析 css class 字符串?我是否缺少任何解决方法?
更新:通过禁用我的 css-loader
中的 'css-modules' 选项设法解决了这个问题。
css class 名称的散列是由于 css-modules
选项。通过禁用此选项,class 名称不再被散列,使外部库能够直接引用它们自己的 classes。
看起来问题并不能通过保留 css-modules
选项轻松解决。