Importing CSS files in Isomorphic React Components

I have a React application with Components written in ES6 - transpiled via Babel and Webpack.

In some places I would like to include specific CSS files with specific Components, as suggested in react webpack cookbook

However, if in any Component file I require a static CSS asset, eg:

import '../assets/css/style.css';

Then the compilation fails with an error:

SyntaxError: <PROJECT>/assets/css/style.css: Unexpected character '#' (3:0)
    at Parser.pp.raise (<PROJECT>node_modulesbabel-corelibacornsrclocation.js:73:13)
    at Parser.pp.getTokenFromCode (<PROJECT>node_modulesbabel-corelibacornsrctokenize.js:423:8)
    at Parser.pp.readToken (<PROJECT>node_modulesbabel-corelibacornsrctokenize.js:106:15)
    at Parser.<anonymous> (<PROJECT>node_modulesbabel-corenode_modulesacorn-jsxinject.js:650:22)
    at Parser.readToken (<PROJECT>node_modulesbabel-corelibacornpluginsflow.js:694:22)
    at Parser.pp.nextToken (<PROJECT>node_modulesbabel-corelibacornsrctokenize.js:98:71)
    at Object.parse (<PROJECT>node_modulesbabel-corelibacornsrcindex.js:105:5)
    at exports.default (<PROJECT>node_modulesbabel-corelibbabelhelpersparse.js:47:19)
    at File.parse (<PROJECT>node_modulesbabel-corelibbabeltransformationfileindex.js:529:46)
    at File.addCode (<PROJECT>node_modulesbabel-corelibbabeltransformationfileindex.js:611:24)

It seems that if I try and require a CSS file in a Component file, then the Babel loader will interpret that as another source and try to transpile the CSS into Javascript.

Is this expected? Is there a way to achieve this - allowing transpiled files to explicitly reference static assets that are not to be transpiled?

I have specified loaders for both .js/jsx and CSS assets as follows:

  module: {
    loaders: [
      { test: /.css$/, loader: "style-loader!css-loader" },
      { test: /.(js|jsx)$/, exclude: /node_modules/, loader: 'babel'}
    ]
  }

View the full webpack config file

FULL DETAILS BELOW:

webpack.common.js - A base webpack config I use, so I can share properties between dev and production.

Gruntfile.js - Gruntfile used for development. As you can see it requires the webpack config above and adds some development properties to it. Could this be causing the problem?

Html.jsx - My HTML jsx component that tries to import/require the CSS. This is an isomorphic app (using Fluxbile), hence needing to have the actual HTML as a rendered component. Using the require statement seen in this file, in any part of my application, gives the error described.

It seems to be something to do with grunt . If I just compile with webpack --config webpack.common.js then I get no errors.

Short answer : It's a node runtime error. Trying to load CSS on the server in isomorphic apps is not a good idea.


You can't require css in the component that you are rendering on the server. One way to deal with it is to check if it's a browser before requiring css.

if (process.env.BROWSER) {
  require("./style.css");
}

In order to make it possible you should set process.env.BROWSER to false (or delete it) on the server server.js

delete process.env.BROWSER;
...
// other server stuff

and set it to true for the browser. You do it with webpack's DefinePlugin in the config - webpack.config.js

plugins: [
    ...
    new webpack.DefinePlugin({
        "process.env": {
            BROWSER: JSON.stringify(true)
        }
    })
]

You can see this in action in gpbl's Isomorphic500 app.


If you're building an isomorphic app with ES6 and want to include CSS when rendering on the server (important so basic styles can be sent down to the client in the first HTTP response) check out the @withStyles ES7 decorator used in React Starter Kit.

This little beauty helps ensure users see your content with styles when the page is first rendered. Here's an example isomorphic app I'm building leveraging this technique. Just search the codebase for @withStyles to see how it's used. It goes a little something like this:

import React, { Component, PropTypes } from 'react';
import styles from './ScheduleList.css';
import withStyles from '../../decorators/withStyles';

@withStyles(styles)
class ScheduleList extends Component {

You can also try this https://github.com/halt-hammerzeit/webpack-isomorphic-tools

or this https://github.com/halt-hammerzeit/webpack-react-redux-isomorphic-render-example

链接地址: http://www.djcxy.com/p/52144.html

上一篇: 使用反应,将子组件函数公开给ref

下一篇: 在同构React组件中导入CSS文件