21

I recently upgraded from Webpack 3 to 4. It's now throwing an error:

Module parse failed: Unexpected character '@' You may need an appropriate loader to handle this file type. | @import './scss/variables.scss'; | | * { @ ./src/index.js 1:0-22

In my styles.scss file, I am doing the following:

@import 'scss/variables.scss';

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: Arial, Helvetica, sans-serif;
}

In my index.js file, I am only doing the following:

import './style.scss';

In my webpack.dev.js, all I changed was an addition of mode: 'development':

const StyleLintPlugin = require('stylelint-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const Dotenv = require('dotenv-webpack');

module.exports = {
    mode: 'development',
    entry: './src/index.js',
    output: {
        filename: 'public/bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: ['babel-loader', 'eslint-loader']
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
            }
        ]
    },
    plugins: [
        new StyleLintPlugin({
            configFile: '.stylelintrc',
            context: 'src',
            files: '**/*.scss',
            failOnError: false,
            quiet: false,
            syntax: 'scss'
        }),
        new ExtractTextPlugin('public/style.css'),
        new Dotenv()
    ]
};

I don't know what change from Webpack 3 to 4 has caused this error.

The issue I'm having is very similar to the issue posted here: Webpack 4 Module parse failed: Unexpected character '@' (1:0)

I have been through all related stackoverflow questions and none of them helped.

Here are the relevant dependencies in my package.json:

"babel-loader": "^7.1.4",
"css-loader": "^0.28.11",
"eslint-loader": "^1.9.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"node-sass": "^4.9.0",
"sass-loader": "^6.0.7",
"style-loader": "^0.20.3",
"stylelint-webpack-plugin": "^0.10.5",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.4"

Here are the relevant scripts in my package.json file, for reference in the comments:

"scripts": {
    "watch": "./node_modules/.bin/webpack --mode development --watch --progress",
    "build": "./node_modules/.bin/webpack --mode production"
},
  • Maybe of help: https://stackoverflow.com/questions/47300984/unexpected-character-you-may-need-an-appropriate-loader-to-handle-this-file – Fusseldieb May 31 '18 at 11:30
  • Thanks for your comment, but I've already been through all related stackoverflow questions and none of them helped me :(. –  May 31 '18 at 11:58
  • 1
    I would suggest trying just the loaders `style-loader`, `css-loader`, `sass-loader` first to find out if the problem is with ExtractTextPlugin. – sdgluck May 31 '18 at 12:05
  • Did you upgrade sass loader to latest version? – Stefano Vuerich May 31 '18 at 12:07
  • Hi @sdgluck I just tried that and unfortunately I'm still getting the same problem, thanks for your suggestion though. –  May 31 '18 at 12:14
  • Hi @StefanoVuerich I have. I did npm update to update all the packages in my project. I'll add the package.json to the question. –  May 31 '18 at 12:14
  • Try also delete node-modules folder and npm install again ;) latest version of sass-loader if 7.0.1 – Stefano Vuerich May 31 '18 at 12:17
  • @Edward did you try with the alpha version of Extract plugin? Seems that the stable version does not work yet with webpack 4 https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/701. You can install the beta with `npm i -D extract-text-webpack-plugin@next` – Raul Rene May 31 '18 at 12:19
  • @StefanoVuerich I deleted the node_modules and did npm install again, and now it's not even running. I'll have to fix this before testing your fix Raul Rene. –  May 31 '18 at 12:28
  • What is not even running? If you could not npm install there is something wrong somewhere else...Anyway I can also confirm Raul's opinion – Stefano Vuerich May 31 '18 at 12:40
  • I've got it running now, just attempting Raul's fix. –  May 31 '18 at 12:42

3 Answers3

9

The problem was the script I was using to run Webpack did not specify the config file. This is what it should look like:

"scripts": {
  "watch": "./node_modules/.bin/webpack --watch --config webpack.dev.js",
},

I believe this was generating the @import problem because it was not loading the css-loader as without specifying the config file like above, it uses a default Webpack development config which does not include the css-loader.

4

As I mentioned in a comment on your question there's an open issue with Webpack 4 compatibility: https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/701

A fix for now is to install the alpha version of the library. I've done a small setup just now to test this and it works with webpack 4.

Install the alpha version npm i -D extract-text-webpack-plugin@next --save. Then install css-loader, sass-loader and node-sass.

Then in the webpack config file:

const ExtractTextPlugin = require('extract-text-webpack-plugin');

...

module: {
    rules: [
        {
            test: /\.(js|jsx)$/,
            use: {
                loader: 'babel-loader'
            },
            exclude: /node_modules/,
            include: path.join(__dirname, 'src')
        },
        {
            test: /\.scss$/,
            loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
        }
    ]
},

plugins: [
    new ExtractTextPlugin('bundle.css'),
]

This correctly worked for me, and also concatenated multiple scss files that were using @import statements.

In package.json it should look like

"extract-text-webpack-plugin": "^4.0.0-beta.0",
"webpack": "^4.8.3"

Edit: Just as a side note, apparently mini-css-extract-plugin works fine with webpack 4.

Raul Rene
  • 10,014
  • 9
  • 53
  • 75
  • Unfortunately this doesn't work for me either. I tried downgrading webpack to 4.8.3 as well copying everything you've done yet it still produces the same issue. –  May 31 '18 at 13:02
  • What's the version of webpack-cli you're using? Also, how are you running the bundle? Have you tried using `rules` instead of `loaders` and removing other plugins? – Raul Rene May 31 '18 at 13:11
  • "webpack-cli": "^2.1.4" - I am using rules instead of loaders now. –  May 31 '18 at 13:12
  • 1
    Strange. I have `webpack-cli: 2.1.3`. I've just tried running with `-p` for production and still works. How are you running the bundle? If it's directly from the cmd line it might be something related to the globally installed npm versions. Try to use a script from package json – Raul Rene May 31 '18 at 13:15
  • I have updated my question to include the scripts I am using. I am running `npm run watch`. –  May 31 '18 at 13:17
  • Can you try to just use something like `"watch": "webpack -d -w --progress"` instead of pointing directly to the node_modules? If that doesn't work, create a script that just prints the version `"bla": "webpack -v"` and check if prints the correct version – Raul Rene May 31 '18 at 13:20
  • It's producing the same issue when I run `webpack -d -w --progress`, and the `webpack -v` displays the correct version, 4.8.3. –  May 31 '18 at 13:22
  • Sorry mate I don't have any other ideas. Check again for the correct extract plugin version in node_modules, make sure you have the alpha installed. Try to setup a small demo with nothing more than an index file, webpack and 2 scss files and see if that works. Then figure out one by one what's breaking. My minimal example is working fine. You could always try the mini-css-extract plugin. – Raul Rene May 31 '18 at 13:26
  • 1
    Thanks for your help, I'll give that a go. –  May 31 '18 at 13:29
1

This worked for me: Replace your webpack styling config to the below code

 module: {
        rules: [
          {
            test: /\.(css|sass|scss)$/,
            use: [
              {
                loader: 'style-loader'
              },
              {
                loader: 'css-loader'
              },
              {
                loader: 'sass-loader'
              }
            ]
          }
        ]
      }

I hope this resolves your issue thanks

happymacarts
  • 2,547
  • 1
  • 25
  • 33