5
votes

I'm trying to process multiple SCSS files into a single external CSS file in Webpack (3.6.0) except I'm encountering issues around the parsing of the @import statements.

Entry index.js contains:

import './styles/main.scss';

Entry SCSS:

@import 'reset.scss';
@import 'global.scss';
@import 'fonts.scss';
@import 'system.scss';

Current webpack:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: {
        app: './src/index.js'
    },
    context: path.resolve(__dirname),

    output: {
        path: path.resolve(__dirname, 'public'),
        filename: 'bundle.js',
    },

    plugins: [
        new CleanWebpackPlugin(['app']),
        new HtmlWebpackPlugin({
            title: 'Minimum-Viable',
            filename: 'index.html',
            template: './public/index.html',
        }),
    ],

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            'es2015',
                            'react',
                        ],
                        plugins: ['transform-class-properties'],
                    },
                },
            },
            {
                test: /\.scss$/,
                include: [
                    path.resolve(__dirname, 'styles')
                ],
                use: [
                    {loader:'style-loader'},
                    {loader:'css-loader'},
                    {loader:'sass-loader'}
                ]
            },
        ],
    },
    resolve: {
        extensions: ['.js','.scss']
    }
};

The Error being thrown is:

ERROR in ./src/styles/main.scss Module parse failed: Unexpected character '@' (1:0)

You may need an appropriate loader to handle this file type. | @import 'reset.scss';

Any pointers gratefully received.

5
The first two line of your file with all the imports should be @import "compass/css3"; and @import"compass/utilities";Pratikshya

5 Answers

5
votes

I managed to reproduce the error and it seems to come from:

include: [
    path.resolve(__dirname, 'styles')
],

The path is the issue cause the loader searches for /styles in ./styles but looking at your entry point:

entry: {
    app: './src/index.js'
},

It should actually be ./src/styles so:

include: [
    path.resolve(__dirname, 'src', 'styles')
],
1
votes

with:

include: [
    path.resolve(__dirname, 'styles')
],

you are instructing webpack to use your loader chain only on files residing in your styles folder.

reset.scss looks like a node dependency usually stored in your node_module, which is excluded from SASS processing by the include option.

Try to remove your SASS include option or to extend it in order to include node_folder or the specific module imported by your styles.

1
votes

Have you tried Extract text webpack plugin

https://github.com/webpack-contrib/extract-text-webpack-plugin

Basically it will collect all of your styles files(imported in your code) and pack it to bundled css which you can then just link to your html.

0
votes

I basically have the same config as you, except for two things:

{
  test: /\.scss$/,
  exclude: /node_modules/,
  use: ["style-loader", "css-loader", "sass-loader"]
}

If your webpack is in a different folder compared to your project root, __dirname may not work out for you. You might need to remove that statement all together or change it to process.cwd(). I can give you another hint and that may be that you are missing the node-sass package. Secondly, you are probably not using the right syntax for webpack version 2 or 3 as shown in the use key.

0
votes

Did you try this way?

index.js:

import './styles/main.scss';
import './styles/reset.scss';
import './styles/global.scss';
import './styles/fonts.scss';
import './styles/system.scss';