Webpack 4 - Module parse failed: Unexpected character '@'

匿名 (未验证) 提交于 2019-12-03 08:57:35

问题:

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" }, 

回答1:

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.



回答2:

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.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!