Использование модулей CSS в компонентах React с помощью Typescript, созданных webpack

Я хочу использовать css-загрузчик с опцией "modules" webpack в приложении React, написанном в Typescript. Этот пример был моей отправной точкой (они используют 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;
}

Независимо от того, что я делаю (попробовал изменить синтаксис импорта, попробовал объявить "require" для ts-loader, описанный здесь, я всегда получаю:

Неподготовленная ошибка: не удается найти модуль "../../../css/tree.css"

во время выполнения и

ошибка TS2307: не удается найти модуль '../../../css/tree.css'.

компилятором TS. Что происходит? Мне кажется, что css-loader даже не испускает ICSS? Или это ts-loader ведет себя неправильно?

Ответы

Ответ 1

import имеет особое значение для TypeScript. Это означает, что TypeScript попытается загрузить и понять импортируемую вещь. Правильный способ - определить require, как вы упомянули, но затем var вместо import:

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

Ответ 2

  • Объявить 'require' согласно документации ts-loader.
  • Используйте 'require' как общий с <any> : require <any> ( "../../../css/tree.css" ).

*. d.ts file

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' не существует в типе '{}'.)

Ответ 3

У меня была аналогичная проблема. Для меня импорт работ:

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

Webpack меняет это, как и любой другой нормальный импорт. Он меняет его на

__webpack_require__(id)

Один из недостатков заключается в том, что вы потеряли контроль над переменной стиля.

Ответ 5

Немного поздно, но вы можете создать файл с именем tree.css.d.ts в той же папке, что и tree.css, которая имеет следующую строку:

export const h3: string;

и по-прежнему использовать оператор импорта import * as styles from ..., и вы по-прежнему получите код завершения и проверки времени компиляции.

Вы можете управлять этими файлами определения вручную или интегрировать встроечные модули css-конвейера (https://github.com/Quramy/typed-css-modules)

Ответ 6

Я тоже получил ту же ошибку

Uncaught Error: не удается найти модуль

После поиска в Google много нашел обходной путь. Я новичок, чтобы реагировать JS и пытается построить с использованием машинописи, поэтому я использовал

реагировать-скрипт-TS

package.But, когда я начал использовать модуль css, столкнулся с проблемой, что класс импорта из './button.css' не работал, поэтому я использовал import './button.css', но в этом было много конфликтов css, более высокая область видимости компонента css всегда переопределяется нижним компонентом. так много гуглил и наконец нашел решение.

Решение Начиная с версии 2.1 create-response-app с поддержкой машинописного текста, так что конвертируйте ваше приложение в 2.1 выше

1.create new application using 'npx create-react-app my-new-app --typescript'
2. replace your old src folder in new solution
3. Rename all your css file with '*.module.css' and change the import based on that.
4. Add your package dependancy if anything missing
5. Run

источник: https://joshblog.net/2018/upgrading-a-react-and-typescript-app-from-react-scripts-ts-to-create-react-app-v2-1/