Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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_modules\babel-core\lib\acorn\src\location.js:73:13)     at Parser.pp.getTokenFromCode (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:423:8)     at Parser.pp.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:106:15)     at Parser.<anonymous> (<PROJECT>\node_modules\babel-core\node_modules\acorn-jsx\inject.js:650:22)     at Parser.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\plugins\flow.js:694:22)     at Parser.pp.nextToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:98:71)     at Object.parse (<PROJECT>\node_modules\babel-core\lib\acorn\src\index.js:105:5)     at exports.default (<PROJECT>\node_modules\babel-core\lib\babel\helpers\parse.js:47:19)     at File.parse (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.js:529:46)     at File.addCode (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.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.

like image 722
duncanhall Avatar asked May 20 '15 10:05

duncanhall


People also ask

Where do I import CSS files into react?

That usually goes at the top of the file where other imports happen: import { React } from "react"; import "./Components/css/App. css"; function App() { return ( <div className="main"> </div> ); } export default App; In this example, a CSS file is imported into an App.

Why I Cannot import CSS file react?

This error is generated because the compiler is only able to import files from the src folder. Here, the CSS file is saved outside the src folder, so the compiler failed to import it. To make this code work, you just have to save the CSS file inside the src folder.


1 Answers

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.

like image 145
Viacheslav Avatar answered Oct 04 '22 16:10

Viacheslav