Стили, не работающие в изоморфной реализации React с использованием webpack

HTML-код, отображаемый на сервере, не содержит CSS. Только когда реакция выполняется на стороне клиента, применяется CSS. Что я делаю неправильно?

Сервер конфигурации Webpack + клиент: (сокращено для краткости)

module.exports = [
  {
    name: "simple-server",
    entry: [path.join(__dirname, "..", "src", "server.js")],
    output: {
      path: path.join(__dirname, "..", "build"),
      filename: "server.js",
      libraryTarget: "commonjs2",
    },
    target: "node",
    externals: [nodeExternals()],
    module: {
      loaders: [
        {
          test: /\.scss$/,
          loaders: ["css", "sass"],
        },
        {
          test: /\.css$/,
          loader: ["css"],
        }
      ],
    },
    resolve: {
      extensions: ["", ".js", ".jsx", ".scss"],
      modulesDirectories: [ "src", "node_modules"],
    },
  },
  {
    name: "simple-client",
    context: path.join(__dirname, "..", "src"),
    entry: {
      app: ["handlers/App", "webpack-hot-middleware/client?path=__webpack_hmr"],
    },
    devtool: "cheap-module-inline-source-map",
    output: {
      path: path.join(__dirname, "..", "build", "assets"),
      filename: "[name].js",
      publicPath: "assets/",
    },
    target: "web",
    module: {
      loaders: [
        {
          test: /\.scss$/,
          loaders: ["style-loader","css-loader?sourceMap","postcss-loader","sass-loader?sourceMap"],
        },
        {
          test: /\.css$/,
          loaders: ["style-loader","css-loader?sourceMap","postcss-loader"],
        }
      ],
    },
    postcss: () => [autoprefixer({ browsers: ["last 5 versions", "> 5%"] })],
    resolve: {
      extensions: ["", ".js", ".jsx", ".scss"],
      modulesDirectories: [
        "src",
        "node_modules",
      ],
    },
    plugins: [
      new webpack.optimize.OccurenceOrderPlugin(),
      new HtmlWebpackPlugin({
        filename: "app.html",
        template: "templates/main.html",
      })
      new webpack.HotModuleReplacementPlugin(),
    ],
  },
];

Компонент образца:

import React from "react";
import "Styles.scss";

export default Component extends .... {}

person Shubham Kanodia    schedule 12.03.2016    source источник
comment
Когда вы просматриваете страницу, видите ли вы ссылку на файл css на dom? а что вы видите во вкладке сети? Он пытается его загрузить и терпит неудачу?   -  person Geraint    schedule 12.03.2016
comment
@Geraint Нет, я не вижу никаких CSS-файлов / встроенных стилей, вводимых в html. Кажется, что стили присутствуют только в .js, который отображается на стороне клиента.   -  person Shubham Kanodia    schedule 12.03.2016
comment
Попробуйте вручную разместить ссылку на css на своей странице индекса html (думаю, вы назвали ее app.html) и посмотрите, работает ли это (просто чтобы определить, проблема ли в этом)   -  person Geraint    schedule 12.03.2016
comment
На данный момент я не распаковываю стиль ни в один файл .css. Если бы я это сделал, я бы дважды загружал стили (файл jsx + css). Как я могу работать как на клиенте, так и на сервере (возможно, путем извлечения стилей в голову) и при этом пользоваться преимуществами hmr?   -  person Shubham Kanodia    schedule 12.03.2016


Ответы (1)


Вы можете указать webpack создать отдельный пакет для css при создании пакета js. И используйте их в заголовке html

<link rel="stylesheet" type="text/css" href="/static/style.css">

(Есть много статей, в которых говорится, что CSS лучше помещать в заголовок html).

Как указать webpack на разделение css:

https://webpack.github.io/docs/stylesheets.html#separate-css-bundle

Суммируя:

Вам необходимо установить:

npm install extract-text-webpack-plugin --save

Добавьте этот плагин в список плагинов:

plugins: [
    new ExtractTextPlugin("style.css")
]

А в загрузчиках:

{
  test: /\.css$/,
  loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
  test: /\.sass$/,
  loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader")
}

Я не уверен, правильно ли это работает с hmr (перезагрузка css), потому что, когда я работаю с hmr, мне не нужен рендеринг на стороне сервера. У меня есть две конфигурации webpack: dev и production. dev config использует hmr и не разделяет css (один пакет) и не отображает серверную часть. И производство не использует hmr, разделяет css и js и рендеринг на стороне сервера.

Вы можете проверить мою конфигурацию:

https://github.com/uhlryk/my-express-react-seed

person Krzysztof Sztompka    schedule 13.03.2016
comment
Возможно, это не лучший подход. Я еще не нашел решения, но этот ответ имеет смысл - stackoverflow.com/a/36023446/2645080 - person Nitin Nain; 05.09.2016