Unexpected character '@' You may need an appropriate loader to handle this file type

vovina picture vovina · Nov 15, 2017 · Viewed 7k times · Source

This is what I get when I try to run webpack: the error I get is:

"ERROR in ./v3/app/styles/main.scss Module parse failed: /Users/vovina/widget-login-react/v3/app/styles/main.scss Unexpected character '@' (1:0) You may need an appropriate loader to handle this file type."

it can't resolve @import, any ideas on this?

my webpack config is as follow:

    const childProcess = require('child_process')
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const ExtractTextPlugin = require('extract-text-webpack-plugin')
    const trimEnd = require('lodash/trimEnd')
    const webpack = require('webpack')
    const path = require('path')

    const ENV = {
      NODE_ENV: process.env.NODE_ENV,
      API: 'https://accounts' + (process.env.NODE_ENV === 'prd' ? '' : '-' 
    + process.env.NODE_ENV),
      BUILD_VERSION: trimEnd(childProcess.execSync('git rev-list HEAD --
    count').toString(), '\n'),
      BUILD_DATE: trimEnd(childProcess.execSync('git log --format="%cd" -n 
    1').toString(), '\n'),
      BUILD_COMMIT_ID: trimEnd(childProcess.execSync('git log --format="%h" 
    -n 1').toString(), '\n')
    }
    const prodLikeEnvironment = process.env.NODE_ENV === 'stg' || 
    process.env.NODE_ENV === 'prd'
    const CSS_MAPS = !prodLikeEnvironment
    module.exports = {

      entry: {
        init: [
          './app/init.js'
        ],
        login: [
          './app/login.js'
        ],
        authentication: [
          './v3/app/authenticator.js'
        ],
        common: [
          './app/common.js'
        ]
      },
      target: 'web',
      output: {
        path: path.join(__dirname, 'dist', process.env.NODE_ENV),
        pathinfo: true,
        publicPath: '/assets/widgets/login/v2/',
        filename: '[name].bundle.js',
        chunkFilename: '[id].bundle.js',
        libraryTarget: 'umd'
      },
      resolve: {
        alias: {
          'react': 'preact-compat',
          'react-dom': 'preact-compat'
        },
        modules: [
          path.resolve('./app'),
          path.resolve('./node_modules')
        ]
      },
      module: {
        loaders: [
          {
            test: /\.jsx?$/,
            loaders: ['babel-loader'],
            exclude: [/bower_components/, /node_modules/]
          },
          {
    // Transform our own .(scss|css) files with PostCSS and CSS-modules
            test: /\.(scss|css)$/,
            include: [path.resolve(__dirname, 'v3/app')],
            options: {
              sourceMap: true
            },
            loader: [
              `style-loader?singleton`,
              `css-loader?modules&importLoaders=1&localIdentName=
    [local]${process.env.CSS_MODULES_IDENT || 
    '_[hash:base64:5]'}&sourceMap=${CSS_MAPS}`,
              'postcss-loader',
              `sass-loader?sourceMap=${CSS_MAPS}`
            ].join('!')
          },
          {
            test: /\.(scss|css)$/,
            exclude: [path.resolve(__dirname, 'v3/app')],
            options: {
            sourceMap: true
            },
            loader: [
              `style-loader?singleton`,
              `css-loader?sourceMap=${CSS_MAPS}`,
              `postcss-loader`,
              `sass-loader?sourceMap=${CSS_MAPS}`
            ].join('!')
          },
          {
            test: /\.(svg|eot|woff|woff2?|ttf|otf)$/,
            use: 'base64-font-loader'
          },
          {
            test: /.json$/,
            loader: 'json'
          },
          {
            test: /\.jpe?g$|\.gif$|\.png$/,
            use: 'base64-image-loader'
          },
          {
            test: /\.html?$/,
            loader: 'html'
          },
          {
            test: /\.js$/,
            loader: 'strip-loader?strip[]=debug,strip[]=console.log,strip[]=console.debug,strip[]=console.info'
          }
        ]
      },
      plugins: [
        new webpack.LoaderOptionsPlugin({
          minimize: true
          // postcss: [
          //   autoprefixer({ browsers: 'last 2 versions' })
          // ]
        }),
        new CopyWebpackPlugin([
    { from: 'public' }
        ]),
        new ExtractTextPlugin('[name].bundle.css'),
        new webpack.DefinePlugin({
          ENV: JSON.stringify(ENV),
    // Only used for react prod bundle. Refer to ENV.NODE_ENV for business 
    logic
          'process.env': {
            'NODE_ENV': JSON.stringify('production')
          }
        }),
        new webpack.NoEmitOnErrorsPlugin(),
        new webpack.optimize.UglifyJsPlugin({
          output: {
            comments: false
          },
          compress: {
            unsafe_comps: true,
            properties: true,
            keep_fargs: false,
            pure_getters: true,
            collapse_vars: true,
            unsafe: true,
            warnings: false,
            screw_ie8: true,
            sequences: true,
            dead_code: true,
            drop_debugger: true,
            comparisons: true,
            conditionals: true,
            evaluate: true,
            booleans: true,
            loops: true,
            unused: true,
            hoist_funs: true,
            if_return: true,
            join_vars: true,
            cascade: true,
            drop_console: true
          }
        })
      ]
    }

Answer

Voro picture Voro · Nov 15, 2017

You are using the (scss|css) twice in your configuration file. Remove that and use the code posted blow: Before using, you must first npm install raw-loader. I think you've already installed the sass-loader.

{
  test: /\.css$/,
  include: helpers.root('src', 'app'),
  loader: 'raw-loader'
},
// // css global which not include in components
{
  test: /\.css$/,
  exclude: helpers.root('src', 'app'),
  use: ExtractTextPlugin.extract({
    use: 'raw-loader'
  })
},

{
  test: /\.scss$/,
  include: helpers.root('src', 'app'),
  use: ['raw-loader', 'sass-loader']
},
// // SASS global which not include in components
{
  test: /\.scss$/,
  exclude: helpers.root('src', 'app'),
  use: ExtractTextPlugin.extract({
    use: ['raw-loader', 'sass-loader']
  })
}

Add my root()function.

var path = require('path'); 
var _root = path.resolve(__dirname, '..'); 
function root(args) {   
    args = Array.prototype.slice.call(arguments, 0);   
    return path.join.apply(path, [_root].concat(args)); 
} 
exports.root = root;

Hope this will work.