在 React 组件中使用由 webpack 构建的 Typescript 的 CSS 模块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35014132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:14:25  来源:igfitidea点击:

Use CSS Modules in React components with Typescript built by webpack

javascriptreactjstypescriptwebpackreact-css-modules

提问by Shady

I want to use the css-loader with the 'modules' option of webpack in a React application written in Typescript. This examplewas my starting point (they are using Babel, webpack and React).

我想在用 Typescript 编写的 React 应用程序中使用带有 webpack 'modules' 选项的 css-loader。这个例子是我的起点(他们使用 Babel、webpack 和 React)。

webpack config

网络包配置

var webpack=require('webpack');
var path=require('path');
var ExtractTextPlugin=require("extract-text-webpack-plugin");

module.exports={
    entry: ['./src/main.tsx'],
    output: {
        path: path.resolve(__dirname, "target"),
        publicPath: "/assets/",
        filename: 'bundle.js'
    },
    debug: true,
    devtool: 'eval-source-map',
    plugins: [
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.UglifyJsPlugin({minimize: true})
    ],
    resolve: {
        extensions: ['', '.jsx', '.ts', '.js', '.tsx', '.css', '.less']
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loader: 'ts-loader'
            },
            {
                test: /\.tsx$/,
                loader: 'react-hot!ts-loader'
            }, {
                test: /\.jsx$/,
                exclude: /(node_modules|bower_components)/,
                loader: "react-hot!babel-loader"
            },
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                loader: "babel-loader"
            }, {
                test: /\.css/,
                exclude: /(node_modules|bower_components)/,
                loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader')
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin("styles.css", {allChunks: true})
    ],
    postcss: function() {
        return [require("postcss-cssnext")()]
    }
}

This is a React component I want to style with an accompanying CSS file:

这是一个我想使用随附的 CSS 文件设置样式的 React 组件:

import React = require('react');
import styles = require('../../../css/tree.css')

class Tree extends React.Component<{}, TreeState> {
...

    render() {
        var components = this.state.components
        return (
            <div>
                <h3 className={styles.h3} >Components</h3>
                <div id="tree" className="list-group">
                    ...
                </div>
            </div>
        )
    }
}

    export = Tree

tree.css

树.css

.h3{
    color: red;
}

No matter what I'm doing (tried changing the import syntax, tried declaring the 'require' for ts-loader, described here, I always get:

无论我在做什么(尝试更改导入语法,尝试为 ts-loader 声明“require”,这里描述,我总是得到:

Uncaught Error: Cannot find module "../../../css/tree.css"

未捕获的错误:找不到模块“../../../css/tree.css”

at runtime and

在运行时和

error TS2307: Cannot find module '../../../css/tree.css'.

错误 TS2307:找不到模块“../../../css/tree.css”。

by the TS compiler. Whats happening? Seems to me that css-loader is not even emitting ICSS? Or is it ts-loader behaving wrong?

通过 TS 编译器。发生了什么?在我看来 css-loader 甚至没有发出 ICSS?还是 ts-loader 行为错误?

采纳答案by James Brantly

importhas special meaning to TypeScript. It means that TypeScript will attempt to load and understand the thing being imported. The right way is to define requirelike you mentioned but then varinstead of import:

import对 TypeScript 有特殊意义。这意味着 TypeScript 将尝试加载和理解正在导入的东西。正确的方法是require像你提到的那样定义,var而不是import

var styles = require('../../../css/tree.css')`

回答by Martin

  1. Declare 'require' as per ts-loader documentation.
  2. Use 'require' as generic with < any >type: require< any >("../../../css/tree.css").
  1. 根据ts-loader 文档声明“需要” 。
  2. 使用 'require' 作为通用< any >类型:require< any >("../../../css/tree.css")

*.d.ts file

*.d.ts 文件

declare var require: {
   <T>(path: string): T;
   (paths: string[], callback: (...modules: any[]) => void): void;
   ensure: (paths: string[], callback: (require: <T>(path: string) => T) => void) => void;
}; 

*.tsx file with component

*.tsx 文件与组件

const styles = require<any>("../../../css/tree.css");
...
<h3 className={styles.h3}>Components</h3>

I know it was already answered, but I was struggling with it for a while before I realized I need to use generic type specification, without that I wasn't able to access content of CSS file. (I was getting error: Property 'h3' does not exists on type '{}'.)

我知道它已经得到了回答,但是在我意识到我需要使用泛型类型规范之前我一直在努力解决它,否则我无法访问 CSS 文件的内容。(我收到错误:类型“{}”上不存在属性“h3”。

回答by Yosuke Kurami

You can use https://github.com/Quramy/typed-css-modules, which creates .d.ts files from CSS Modules .css files. Please see also https://github.com/css-modules/css-modules/issues/61#issuecomment-220684795

您可以使用https://github.com/Qramy/typed-css-modules,它从 CSS Modules .css 文件创建 .d.ts 文件。另请参阅https://github.com/css-modules/css-modules/issues/61#issuecomment-220684795

回答by Krzysztof Sztompka

I had similar problem. For me, works import:

我有类似的问题。对我来说,作品导入:

import '../../../css/tree.css';

Webpack change this like any other normal imports. It change it to

Webpack 像任何其他普通导入一样改变它。它改变它

__webpack_require__(id)

One drawback is that you lost control on style variable.

一个缺点是您失去了对样式变量的控制。

回答by Gareth Evans

A bit late to game but you can create a file called tree.css.d.ts in the same folder as tree.css that has this line:

游戏有点晚了,但您可以在与 tree.css 相同的文件夹中创建一个名为 tree.css.d.ts 的文件,其中包含以下行:

export const h3: string;

and still use the import statement import * as styles from ...and you will still getcode completion and compile time checking.

并且仍然使用 import 语句import * as styles from ...,你仍然会得到代码完成和编译时检查。

You can either manage these definition files manually or you could integrate typed-css-modules into your build pipeline (https://github.com/Quramy/typed-css-modules)

您可以手动管理这些定义文件,也可以将 typed-css-modules 集成到构建管道中 ( https://github.com/Qramy/typed-css-modules)