首页 文章

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

提问于
浏览
17

我想在一个用Typescript编写的React应用程序中使用带有webpack的'modules'选项的css-loader . This example是我的出发点(他们使用的是Babel,webpack和React) .

webpack配置

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")()]
    }
}

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

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

.h3{
    color: red;
}

无论我对ts-loader有什么要求',描述here,我总是得到:

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

在运行时和

错误TS2307:找不到模块'../../../css/tree.css' .

由TS编译器 . 发生了什么?在我看来,css-loader甚至没有发射ICSS?或者ts-loader行为错误?

5 回答

  • 2

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

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

    Webpack像其他正常导入一样改变它 . 它改变为

    __webpack_require__(id)
    

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

  • 7
  • 0

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

    var styles = require('../../../css/tree.css')`
    
  • 11
    • 根据ts-loader documentation声明'require' .

    • 使用'require'作为通用 < any > 类型: require< any >("../../../css/tree.css") .

    • .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文件与组件
    const styles = require<any>("../../../css/tree.css");
    ...
    <h3 className={styles.h3}>Components</h3>
    

    我知道它已经回答了,但是在我意识到我需要使用泛型类型规范之前我已经挣扎了一段时间,没有我无法访问CSS文件的内容 . (我收到错误:'{}'类型的属性'h3'不存在 . )

  • 2

    游戏有点晚,但是您可以在与具有以下行的tree.css相同的文件夹中创建名为tree.css.d.ts的文件:

    export const h3: string;
    

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

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

相关问题