Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
256 views
in Technique[技术] by (71.8m points)

javascript - 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>
ode_modulesabel-corelibacornsrclocation.js:73:13)
    at Parser.pp.getTokenFromCode (<PROJECT>
ode_modulesabel-corelibacornsrcokenize.js:423:8)
    at Parser.pp.readToken (<PROJECT>
ode_modulesabel-corelibacornsrcokenize.js:106:15)
    at Parser.<anonymous> (<PROJECT>
ode_modulesabel-core
ode_modulesacorn-jsxinject.js:650:22)
    at Parser.readToken (<PROJECT>
ode_modulesabel-corelibacornpluginsflow.js:694:22)
    at Parser.pp.nextToken (<PROJECT>
ode_modulesabel-corelibacornsrcokenize.js:98:71)
    at Object.parse (<PROJECT>
ode_modulesabel-corelibacornsrcindex.js:105:5)
    at exports.default (<PROJECT>
ode_modulesabel-corelibabelhelpersparse.js:47:19)
    at File.parse (<PROJECT>
ode_modulesabel-corelibabelransformationfileindex.js:529:46)
    at File.addCode (<PROJECT>
ode_modulesabel-corelibabelransformationfileindex.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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...