Webpack 4无法正确解析SCSS中的url()

时间:2018-10-27 13:03:08

标签: javascript html css webpack

我已经在下面发布了用于生产环境的Webpack配置。我试图在我的一个SCSS文件中使用background-image: url(../img/chevron-thin-right.svg);,但是它被解析为background-image: url([object Module]),因此无法正常工作。我正在尝试将纯SCSS和HTML项目移植到Webpack捆绑的react应用程序中,因此上述方法可以正常工作。任何修复将不胜感激。

webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const outputDirectory = 'dist';

module.exports = {
  entry: './src/client/index.js',
  output: {
    path: path.join(__dirname, outputDirectory),
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Production',
      template: './public/index.html',
      favicon: './public/favicon.ico',
      hash: true,
      filename: 'index.html'
    })
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.(jpg|png|woff|woff2|eot|ttf)$/,
        use: {
          loader: 'file-loader?limit=100000&name=images/[name].[ext]'
        }
      },
      {
        test: /\.svg$/,
        use: [
          "babel-loader",
          {
            loader: "react-svg-loader",
            options: {
              svgo: {
                plugins: [
                  { 
                    removeTitle: true,
                    removeComments: true
                  }
                ],
                floatPrecision: 2
              }
            }
          }
        ]
      }
    ]
  }
};

webpack.prod.js

const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const common = require('./webpack.common.js');
const path = require('path');
const autoprefixer = require('autoprefixer');

module.exports = {};

module.exports = merge(common, {
  mode: 'production',
  optimization: {
    splitChunks: {
      cacheGroups: {
        styles: {
          name: 'styles',
          test: /\.css$/,
          chunks: 'all',
          enforce: true
        }
      }
    }
  },
  plugins: [
    new CleanWebpackPlugin(['dist']),
    new MiniCssExtractPlugin({
      filename: '[name].css'
    })
  ],
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader, 
          {
            loader: 'css-loader',
            options: {
              sourceMap: true,
              root: path.resolve(__dirname),
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: () => [
                autoprefixer({
                  'browsers': ['last 2 versions', 'ie >= 10'],
                }),
              ],
              sourceMap: true,
            },
          },
          {
            loader: 'sass-loader',
            options: {
              outputStyle: 'compressed',
              sourceMap: true,
              includePaths: [
                './src/client/style/scss',
              ],
            },
          }
        ]
      }
    ]
  }
});

1 个答案:

答案 0 :(得分:2)

万一其他人正在寻找答案,我就能解决。这是由于未通过url加载器加载关联的SVG。重新添加svg时出现了另一个问题,因为我想用作React组件的嵌入式SVG遇到了错误,因为它们现在通过url加载器而不是我的react-svg加载器。

下面是正在工作的webpack.common.js和webpack.prod.js保持不变。解决方案是通过将所有内联扩展名从.svg转换为.inline.svg并相应地调整webpack配置,以区分我的内联和外部SVG

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const outputDirectory = 'dist';

module.exports = {
  entry: './src/client/index.js',
  output: {
    path: path.join(__dirname, outputDirectory),
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Production',
      template: './public/index.html',
      favicon: './public/favicon.ico',
      hash: true,
      filename: 'index.html'
    })
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
        exclude: /\.inline.svg$/,
        use: {
          loader: 'url-loader?limit=1000&name=images/[name].[ext]'
        }
      },
      {
        test: /\.inline.svg$/,
        use: [
          "babel-loader",
          {
            loader: "react-svg-loader",
            options: {
              svgo: {
                plugins: [
                  { 
                    removeTitle: true,
                    removeComments: true
                  }
                ],
                floatPrecision: 2
              }
            }
          }
        ]
      }
    ]
  }
};