sekoyo / universal-react

A universal react starter, with routing, meta, title, and data features
242 stars 50 forks source link

Adding universal CSS import support #35

Open krzksz opened 7 years ago

krzksz commented 7 years ago

Hey! First of all, I must say I'm really impressed with all the work you've done on this project and the simplicity it has with such non-trivial task of setting up universal react stack!

Motivation

These are the points I want to achieve:

Problem

Actually, I got stuck right at the first point above. What I did is I changed following code in webpack.config.js:

module: {
    loaders: [
      {
        test: /\.js?$/,
        loader: 'babel-loader',
        include: path.join(__dirname, 'app'),
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
            options: {
              sourceMap: true,
            },
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },

and added simple import in app/components/UserCard.js:

import React from 'react';
import PropTypes from 'prop-types';
import './UserCard.css'; // Simple CSS import

const UserCard = ({ user }) => (
/* ... */

and after running npm start babel blew up:

/Users/krzksz/Sites/universal-react/node_modules/babel-core/lib/transformation/file/index.js:590
      throw err;
      ^

SyntaxError: /Users/krzksz/Sites/universal-react/app/components/UserCard.css: Unexpected token, expected ; (1:3)
> 1 | ul {
    |    ^
  2 |   background: yellow;
  3 | }
  4 |
    at Parser.pp$5.raise (/Users/krzksz/Sites/universal-react/node_modules/babylon/lib/index.js:4454:13)

Funny thing is that if I add this import after the server has started, webpack is parsing it correctly, even HMR works. Unfortunately, it is not the case on production build.

Cause

As far as I understand babel is trying to follow my import for CSS file but it obviously can't understand it, which is due to this require: https://github.com/DominicTobias/universal-react/blob/7a25583f54ca1093bde8a2947f1511be7fe9b477/server.js#L48 In order for it to work, webpack would probably be needed to also make a separate server bundle.

Solution

I'm not really sure here so maybe you can give some insight. If I understand correctly then we would have to introduce separate webpack builds for server and client code, which would introduce some complexity and I'm not really sure I'm up for the challenge 🤔

krzksz commented 7 years ago

I can see it is somehow a duplicate of https://github.com/DominicTobias/universal-react/issues/31 so feel free to close this one if it doesn't give any additional insight into the issue 👍

dalebaldwin commented 7 years ago

Here is how I got it working with sass/scss

node-sass sass-loader postcss-loader style-loader css-loader extract-text-webpack-plugin

Update your entry array (webpack config) to include a path to your entry point file.

entry: [ 'webpack-hot-middleware/client', './src/index.js', './src/styles/style.scss' ],

In your plugins add the following

new webpack.LoaderOptionsPlugin({ minimize: true })

and

new ExtractTextPlugin({ filename: 'style.css', allChunks: true, })

now add a new rule

{
        test: /\.scss$/,
        use:  ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [{
            loader: 'css-loader', options: {
              sourceMap: true
            }
          },{
            loader: 'postcss-loader', options: {
              sourceMap: true
            }
          },{
            loader: 'sass-loader', options: {
              sourceMap: true
            }
          }]
        }),
      }