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;