Используя Typescript, Webpack 4 и React, каждый раз, когда я включаю файл scss, имя стиля не определено в className

Я создаю приложение React, используя Typescript и Webpack 4. Я пытаюсь включить имена классов из файла scss в свои компоненты, но когда я делаю это, имя класса не определено.

Большая проблема, с которой я сталкиваюсь, заключается в том, что многие учебники и страницы в Интернете рекомендуют использовать ExtractTextPlugin, но это несовместимо с webpack 4. Вот почему я должен использовать MiniCssExtractPlugin и typings-for-css-modules-loader.

Ниже приведены мои зависимости в моем package.json.

"devDependencies": {
    "@types/react": "^16.4.14",
    "@types/react-dom": "^16.0.7",
    "@types/react-redux": "^6.0.9",
    "@types/redux-saga": "^0.10.5",
    "awesome-typescript-loader": "^5.2.1",
    "css-loader": "^1.0.0",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.4.2",
    "node-sass": "^4.9.3",
    "npm-check": "^5.8.0",
    "sass-loader": "^7.1.0",
    "source-map-loader": "^0.2.4",
    "style-loader": "^0.23.0",
    "typescript": "^3.0.3",
    "typings-for-css-modules-loader": "^1.7.0",
    "webpack": "^4.18.1",
    "webpack-cli": "^3.1.0"
},
"dependencies": {
    "es6-promise": "^4.2.5",
    "little-loader": "^0.2.0",
    "query-string": "^6.1.0",
    "react": "^16.5.0",
    "react-dom": "^16.5.0",
    "react-redux": "^5.0.7",
    "redux": "^4.0.0",
    "redux-saga": "^0.16.0"
}

Мой webpack.config.js включает в себя следующее в разделе module => rules, а также другие вещи для обработки моих файлов машинописного текста и т. д.

{
    test: /\.(s*)css$/,
    use: [
        "style-loader",
        {
            loader: MiniCssExtractPlugin.loader,
            options:
            {
                publicPath: path.resolve(__dirname, './dist')
            }
        },
        {
            loader: 'typings-for-css-modules-loader',
            options:
            {
                importLoaders: 1,
                modules: true,
                namedExport: true,
                camelCase: true,
                localIdentName: '[name]_[local][hash:base64:5]',
                banner: "// *** Generated File - Do not Edit ***"
            }
        },
        {
            loader: "sass-loader",
            options:
            {
                sourceMap: true,
                modules: true
            }
        }
    ]
}

У меня есть файл scss с именем map.styles.scss, который содержит только следующие

.map-container {
    margin: 0 auto;
    overflow: hidden;    
}

При запуске сборки веб-пакета создается следующий файл с именем map.styles.scss.d.ts

// *** Generated File - Do not Edit ***
export const mapContainer: string;

Теперь я могу ссылаться на файл в моем машинописном тексте с соответствующей ссылкой на className следующим образом

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as styles from './map.styles.scss';

export class Map extends React.Component {

    render() {        
        return (                    
            <div ref='map' className = {styles.mapContainer}>         
                Loading map...                    
            </div>                  
        );        
    }
}

Проблема в том, что пока стили являются объектами, mapContainer не определен. В результате, когда мое приложение построено, className отсутствует, потому что нет значения для применения, и поэтому стиль не работает.

Мне кажется странным, что я могу ссылаться на стили, но не получаю строку, представляющую класс. Может кто-то указать мне верное направление?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
1 207
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел проблему.

Проблема заключалась в использовании как MiniCssExtractPlugin, так и style-loader. Это сгенерировало два файла, на которые пытался ссылаться объект стилей.

Один сгенерировал словарь ключей, который соответствовал ссылке styles.mapContainer на значение, а другой содержал загрузку javascript, что я не на 100% понимаю, что он сделал.

Мне нужен был тот, со словарем ценностей. Вынув загрузчик стилей, я остался с файлом словаря, а не с другим, а затем, поскольку не было двусмысленности, он взял локализованные имена классов.

Ниже приведена моя последняя конфигурация веб-пакета для создания файла css.

{
    test: /\.(s*)css$/,
    use: [
        {
            loader: MiniCssExtractPlugin.loader,
            options:
            {
                publicPath: path.resolve(__dirname, './dist')
            }
        },
        {
            loader: 'typings-for-css-modules-loader',
            options:
            {
                importLoaders: 1,
                modules: true,
                namedExport: true,
                camelCase: true,
                localIdentName: '[name]_[local][hash:base64:5]',
                banner: "// *** Generated File - Do not Edit ***"
            }
        },
        {
            loader: "sass-loader",
            options:
            {
                sourceMap: true,
                modules: true
            }
        }
    ]
}

Поскольку вы нашли решение, примите этот ответ как правильный, чтобы отметить вопрос как решенный.

Adam 20.09.2018 00:12

Другие вопросы по теме