Ни загрузчик стилей, ни MiniCssExtractPlugin не решают мою проблему - PullRequest
0 голосов
/ 08 мая 2020

Я боролся с этой проблемой в течение нескольких месяцев, но неоднократно никогда не продвигался вперед, так что этот вопрос - мое последнее средство. проекты, над которыми я работаю. Я намерен иметь повторно используемые компоненты React для кода браузера, а также некоторые чистые функции JavaScript, которые можно использовать как в браузере, так и в Node. В нынешнем виде мой пакет содержит только последние (JavaScript функций) и один компонент React, который использует чистый JavaScript для стилизации, а не CSS или SASS.

То, что я хочу - это возможность стилизовать мои повторно используемые компоненты React с использованием SASS.

Но Webpack оказался для меня кошмаром. Между двумя загрузчиками, которые позволяют стилизовать style-loader и MiniCSSExtractPlugin, я не могу получить то, что хочу.

style-loader выдает ошибки, где [window / define / document etc.] is not defined независимо от моего webpack.config.js файлы libraryTarget. Я знаю, что это означает, что он не работает в браузере, но, честно говоря, я не совсем понимаю, почему это не так, когда я просто пытаюсь использовать компонент React в одном из своих проектов веб-приложений.

MiniCssExtractPlugin выглядел как спасительная благодать, но после извлечения CSS из SASS в другой файл ничего не происходит. Когда я проверяю свой элемент во внешнем проекте, CSS просто не применяется. Я понятия не имею, почему. Даже когда я установил свои параметры css-loader, чтобы разрешить CSS модули, я могу распечатать сопоставление classNames с именами хешированных модулей, но все еще без приложения. Это сводит меня с ума.

Я даже не знаю, что вам нужно увидеть, чтобы мне помочь, но вот как минимум моя конфигурация Webpack.

webpack.config. js

const nodeExternals = require('webpack-node-externals');
const path = require('path');

const clientConfig = {
  entry: './src/client',
  output: {
    path: path.join(__dirname, './client'),
    filename: 'index.js',
    libraryTarget: 'commonjs',
  },
  module: {
    rules: [
      {
        test: /\.s?css$/i,
        use: [
          // MiniCssExtractPlugin.loader,
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              modules: true,
            },
          },
          'sass-loader',
        ],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
    ],
  },
  target: 'web',
};

const serverConfig = {
  entry: './src/server',
  output: {
    path: path.join(__dirname, './server'),
    filename: 'index.js',
    libraryTarget: 'commonjs',
  },
  target: 'node',
  externals: [nodeExternals()],
};

module.exports = [
  clientConfig,
  serverConfig
];

Любые другие соответствующие файлы могут быть компонентами React, пытающимися импортировать файлы S CSS для использования. например,

import React, { Component } from 'react';
import classnames from 'classnames';
import css from '../../styles/form.module.scss';

class ITextArea extends Component {
  constructor(props) {
    super(props);
    this.state = { rows: props.minRows };
  }

  handleTextChange = event => {
    this.props.onChange(event);
    const text = event.target.value;
    this.setState({ wordCount: text.length });
  };

  render() {
    const { className, name, placeholder, value } = this.props;
    return (
      <textarea
        name={name}
        placeholder={placeholder}
        className={classnames(className, css.textarea)}
        rows={this.state.rows}
        value={value || ''}
        onChange={this.handleTextChange}
      />
    );
  }
}

/** For shorter text inputs */
export class ShortTextArea extends Component {
  render() {
    return (
      <ITextArea minRows={1} {...this.props} />
    );
  }
}

/** For long text inputs with word counters */
export class LongTextArea extends Component {
  constructor(props) {
    super(props);
    this.state = {
      wordCount: props.value ? props.value.length : 0
    };
  }

  static getDerivedStateFromProps(props) {
    return { wordCount: props.value ? props.value.length : 0 };
  }

  render() {
    return (
      <div>
        <ITextArea minRows={3} {...this.props} />
        <label
          className={classnames(this.props.wordCountClassName, css.wordCount)}>
          {this.state.wordCount}
        </label>
      </div>
    );
  }
}

Вы должны мне помочь, ПОЖАЛУЙСТА. Бьюсь головой о стену. Если потребуется дополнительная информация, дайте мне знать!

...