SyntaxError, unexpected token loading CSS

babel tries to parse a CSS file even though proper loaders are defined in the webpack.config.js.

When I run npm run dev, I get the following error. Notice that this error is thrown on the first run only.

SyntaxError: /Users/user/dashboard/shared/components/TopBar/styles/AddDashboard.styl: Unexpected token (1:0)
> 1 | .add-dashboard-toggle
    | ^
  2 |   text-align center
  3 |   width 20px
  4 |
    at Parser.pp.raise (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/location.js:22:13)
    at Parser.pp.unexpected (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/util.js:91:8)
    at Parser.pp.parseExprAtom (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/expression.js:510:12)
    at Parser.<anonymous> (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/plugins/jsx/index.js:404:22)
    at Parser.parseExprAtom (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/plugins/jsx/index.js:404:22)
    at Parser.pp.parseExprSubscripts (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/expression.js:265:19)
    at Parser.pp.parseMaybeUnary (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/expression.js:245:19)
    at Parser.pp.parseExprOps (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/expression.js:176:19)
    at Parser.pp.parseMaybeConditional (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/expression.js:158:19)
    at Parser.pp.parseMaybeAssign (/Users/user/dashboard/node_modules/babel-core/node_modules/babylon/lib/parser/expression.js:121:19)

Here is my webpack.config.js:

import autoprefixer from 'autoprefixer';
import config from '../../config';
import path from 'path';
import webpack from 'webpack';

const webpackConfig = {
  devtool: 'inline-source-map', 
  entry: [
    'webpack-dev-server/client?http://' + config.get('webpack_host') + ':8081/',
    'webpack/hot/only-dev-server',
    './client'
  ],
  eslint: {
    configFile: '.eslintrc',
    emitWarnings: true
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js'
  },
  resolve: {
    modulesDirectories: ['node_modules', 'shared'],
    extensions: ['', '.js', '.jsx', '.css', '.styl']
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loaders: ['react-hot', 'babel']
      },
      /* eslint-disable */
      { test: /\.woff(\?.*)?$/,  loader: "url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff" },
      { test: /\.woff2(\?.*)?$/, loader: "url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff2" },
      { test: /\.ttf(\?.*)?$/,   loader: "url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/octet-stream" },
      { test: /\.eot(\?.*)?$/,   loader: "file-loader?prefix=fonts/&name=[path][name].[ext]" },
      { test: /\.svg(\?.*)?$/,   loader: "url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=image/svg+xml" },
      /* eslint-enable */
      {
        test: /\.styl$/,
        loader: config.get('globals').__DEV__
          ? 'style!css!stylus'
          : ExtractTextPlugin.extract('stylus', 'css!postcss!stylus')
      }
    ]
  },
  postcss: [ autoprefixer({ browsers: ['last 2 versions'] }) ],
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new ExtractTextPlugin('app.css', { allChunks: true }),
    new webpack.NoErrorsPlugin()
  ],
  devServer: {
    hot: true,
    proxy: {
      '*': 'http://' + config.get('webpack_host') + ':' + config.get('webpack_port')
    },
    host: config.get('webpack_host')
  }
};

export default webpackConfig;

Here is my package.json:

{
  "name": "dashboard",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "NODE_PATH=$NODE_PATH:./shared node --harmony .",
    "dev": "NODE_ENV=development && npm run start & webpack-dev-server --progress --color --port 8081 -d --display-error-details",
    "build": "NODE_ENV=production webpack --progress --color -p --config webpack.prod.config.js"
  },
  "dependencies": {
    "axios": "0.7.0",
    "express": "4.13.3",
    "font-awesome": "4.5.0",
    "history": "1.16.0",
    "immutable": "3.7.5",
    "object-assign": "4.0.1",
    "react": "0.14.3",
    "react-dom": "0.14.3",
    "react-redux": "4.0.0",
    "react-router": "1.0.2",
    "redux": "3.0.4"
  },
  "devDependencies": {
    "autoprefixer": "6.1.2",
    "babel": "6.3.13",
    "babel-core": "6.3.17",
    "babel-eslint": "5.0.0-beta6",
    "babel-loader": "6.2.0",
    "babel-plugin-syntax-class-properties": "^6.3.13",
    "babel-plugin-syntax-decorators": "6.3.13",
    "babel-plugin-syntax-object-rest-spread": "^6.3.13",
    "babel-plugin-transform-class-properties": "^6.3.13",
    "babel-plugin-transform-object-rest-spread": "^6.3.13",
    "babel-preset-es2015": "6.3.13",
    "babel-preset-react": "6.3.13",
    "babel-preset-stage-0": "6.3.13",
    "babel-preset-stage-1": "6.3.13",
    "babel-register": "6.3.13",
    "css-loader": "0.23.0",
    "eslint": "1.10.3",
    "eslint-config-airbnb": "2.0.0",
    "eslint-loader": "1.1.1",
    "eslint-plugin-import": "0.11.0",
    "eslint-plugin-react": "3.11.3",
    "extract-text-webpack-plugin": "0.9.1",
    "file-loader": "0.8.5",
    "node-sass": "3.4.2",
    "postcss-loader": "0.8.0",
    "react-hot-loader": "1.3.0",
    "sass-loader": "3.1.2",
    "style-loader": "0.13.0",
    "stylus-loader": "1.4.2",
    "url-loader": "0.5.7",
    "webpack": "1.12.9",
    "webpack-dev-server": "1.14.0"
  }
}

My /Users/user/dashboard/shared/components/TopBar/AddDashboard.jsx contains the following code:

import React from 'react';

import './styles/AddDashboard.styl';

export default class AddDashboard extends React.Component {
  render() {
    return (
      <li className="pure-menu-item top-bar-container">
        <a href="#" className="pure-menu-link add-dashboard-toggle"><i className="fa fa-plus" /></a>
      </li>
    );
  }
}

The interesting thing is that if I comment out the following line:

import './styles/AddDashboard.styl';

… the build is successful, and I can see the front page. Then I can even uncomment the same line and Webpack will pickup changes and rebuild the project without an error. It means the loaders have been successfully loaded at that point.

Therefore, I guess Webpack is not loading the loaders on the first run but only after the first build.

I am out of ideas which is why I have posted here. Any help will be greatly appreciated.

Author: Fantashit

10 thoughts on “SyntaxError, unexpected token loading CSS

  1. I think I found out why it didn’t work on the first place. Though Webpack allows requiring static assets on the client side, babel, which compiles the server code, fails to do so as on the server side Node’s require understands only JS files. This means that server side rendering is not possible with the default Webpack and babel.

    The only way to truly render all the code, including static files, on the server side is through the webpack-isomorphic-tools module that does Webpack’s work on the server side code. Refer to https://github.com/halt-hammerzeit/webpack-isomorphic-tools to learn about it.

    If anybody finds a better way, maybe in the future, I would be glad to know. In the meantime, closing this issue.

  2. I had exactly the same issue with some css and sass files. The workaround was the following one:

    require('babel-core/register')({
      presets: ['es2015', 'react']
    });
    require.extensions['.scss'] = () => {
      return;
    };
    require.extensions['.css'] = () => {
      return;
    };

    So in your case, just try this:

    require.extensions['.styl'] = () => {
      return;
    };
  3. My recommendation, for supporting css modules is to use css-modules-require-hook. Follow the demo project here, or I have an example with server side rendering here.

    I tried to use static files e.g. svg images with server rendering and obviously ran into errors, so until there is a solution as nice as the above one for css modules, I am not using static svg in webpack for server rendering. Webpack isomorphic tools might be the answer, but it seems quite complex to me, possibly just needs some easier demos, and I’m not sure if it supports just using Express or Koa rather than webpack-dev-server.

  4. Stupid question in reference to johndous‘s answer: where should I write that code? I’m very new to all this so I had a hard time understanding where to put it. I tried putting it in my webpack.config.js but had no luck.

  5. Hi @purpleladydragons, sorry if this is too late. The origin of this problem is in the server-side rendering of the app. You are probably already using require('babel-register') at the top of your server.js file. You have to add his solution just beside the babel-register code.


    If you are using React, johndous solution may produce that the server-side rendering of your component and the client-side to be different. At the end, with his solution, in your server-side render, you are practically ignoring (or returning void) all references to CSS. Meanwhile, your Webpack is creating your client bundle with the CSS included. This difference will make React to throw you an error telling you about the difference and that it will ignore the server-side rendered component and will rerender your component from your client bundle.

    To solve that issue, I recommend using the already proposed css-modules-require-hook or webpack-isomorphic-tools . The former is easier to use but I think only works CSS, SCSS… The latter I think it works with images and other types of files.

    In my case, with css-modules-require-hook, I just had to add the following code on top of my server.js file:

    // New. Needs to be on top of babel-register
    require('css-modules-require-hook')({
        generateScopedName: '[name]__[local]___[hash:base64:5]',
    });
    require('babel-register')({
        presets: ['react', 'es2015', 'stage-2']
    });
    
  6. Thanks a lot dear @top1st , I ❤️ you bro, I, LOVE, YOU, I can not explain my feeling 😭 This is tears of happiness, I love you @top1st , I’m indebted to you for the rest of my life. 🙇

    And also special thanks to @lmammino , dear friend who help me a lot. thanks All… 💋 💋 💋

    For Seeing my simple source code of this issue and the sample of fixed by @top1st help, follow this This Link

Comments are closed.