Module parse failed: Unexpected character '@'

I’ve modified my webpack config to suit a React application that lives inside a Sage theme.

I’m now getting this issue when I try to build or watch. Baffled to the high heavens here, no idea how to fix and can’t find anything conclusive online. Anyone else had this issue?

Module parse failed: Unexpected character '@'
You may need an appropriate loader to handle this file type.
| @import "base/_config";
| @import "vendor/_vendor";

Webpack config attached

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const CopyGlobsPlugin = require('copy-globs-webpack-plugin');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');

const config = require('./config');

const assetsName = '[name]';

let webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  //   devtool: 'cheap-module-source-map',

  // Output
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsName}.js`
  },

  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        include: config.paths.assets,
        use: 'eslint'
      },

      {
        test: /.js?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              plugins: ['transform-decorators-legacy', 'transform-class-properties', 'recharts'],
              presets: [
                [
                  'env',
                  {
                    targets: {
                      node: '6',
                      browsers: ['last 3 versions', 'safari >= 7']
                    }
                  }
                ],
                'react',
                'stage-0'
              ]
            }
          }
        ]
      },

      {
        test: /\.scss$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            { loader: 'css-loader', options: { sourceMap: config.enabled.sourceMaps } },
            {
              loader: 'postcss-loader',
              options: {
                config: { path: __dirname, ctx: config },
                sourceMap: config.enabled.sourceMaps
              }
            },
            { loader: 'resolve-url', options: { sourceMap: config.enabled.sourceMaps } },
            { loader: 'sass-loader', options: { sourceMap: config.enabled.sourceMaps } }
          ]
        })
      },

      {
        test: /\.css$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            { loader: 'css-loader', options: { sourceMap: config.enabled.sourceMaps } },
            {
              loader: 'postcss-loader',
              options: {
                config: { path: __dirname, ctx: config },
                sourceMap: config.enabled.sourceMaps
              }
            }
          ]
        })
      },

      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg|ico)$/,
        include: config.paths.assets,
        loader: 'url',
        options: {
          limit: 4096,
          name: `[path]${assetsName}.[ext]`
        }
      },
      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg|ico)$/,
        include: /node_modules/,
        loader: 'url',
        options: {
          limit: 4096,
          outputPath: 'vendor/',
          name: `${config.cacheBusting}.[ext]`
        }
      }
    ]
  },

  resolve: {
    extensions: ['.js', '.jsx', '.es6'],
    modules: [config.paths.assets, 'node_modules'],
    enforceExtension: false
  },

  resolveLoader: {
    moduleExtensions: ['-loader']
  },

  externals: {
    jquery: 'jQuery'
  },

  plugins: [
    new CleanPlugin([config.paths.dist], {
      root: config.paths.root,
      verbose: false
    }),
    new FriendlyErrorsWebpackPlugin(),
    new CopyGlobsPlugin({
      pattern: config.copy,
      output: `[path]${assetsName}.[ext]`,
      manifest: config.manifest
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsName}.css`,
      allChunks: true,
      disable: config.enabled.watcher
    }),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery'
    }),
    new webpack.LoaderOptionsPlugin({
      debug: config.enabled.watcher,
      stats: { colors: true }
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.s?css$/,
      options: {
        output: { path: config.paths.dist },
        context: config.paths.assets
      }
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.js$/,
      options: {
        eslint: { failOnWarning: false, failOnError: true }
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      mangle: true,
      compress: {
        warnings: false,
        pure_getters: true
      },
      output: {
        comments: false
      },
      exclude: [/\.min\.js$/gi]
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new CompressionPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0
    })
  ]
};

if (config.env.production) {
  webpackConfig.plugins.push(new webpack.NoEmitOnErrorsPlugin());
}

if (config.enabled.watcher) {
  webpackConfig.entry = require('./util/addHotMiddleware')(webpackConfig.entry);
  webpackConfig = merge(webpackConfig, require('./webpack.config.watch'));
}

module.exports = webpackConfig;

If you do a diff on your config versus the one that’s in the repo you can see that you’ve changed the whole build setup for styles.

There’s a lot going on when viewing the diff of the configs. We can’t really support custom build setups over here, you might want to post over at Stack Overflow.