Webpack - resolve-url-loader 无法正确解析路径

Posted

技术标签:

【中文标题】Webpack - resolve-url-loader 无法正确解析路径【英文标题】:Webpack - resolve-url-loader does not resolve paths correctly 【发布时间】:2020-08-05 04:37:03 【问题描述】:

在我的 webpack 配置中正确设置 resolve-url-loader 时遇到问题。它似乎根本无法解析 scss 文件中的路径。

这是我的项目文件夹结构:

├───config
│   └───jest
├───public
│   └───assets
│       ├───css
│       ├───fonts
│       ├───images
│       │   ├───background
│       │   ├───icons
│       │   ├───illustration
│       │   ├───logo
│       │   └───projects
│       │       ├───one
│       │       └───two
│       ├───js
│       └───scss
│           ├───blog
│           ├───common
│           ├───default
│           ├───elements
│           ├───header
│           └───template
├───scripts
└───src
    ├───component
    │   ├───common
    │   ├───footer
    │   ├───header
    │   └───slider
    ├───elements
    │   ├───blog
    │   ├───common
    │   ├───portfolio
    │   ├───projects
    │   └───tab
    └───home

您将在下面找到webpack.config.js 的外观。这有点复杂,但我试图隐藏所有我认为与解决此问题无关的代码块。通常use 方法中的加载器链是由文件开头定义的getStyleLoaders 函数创建的。如果preProcessor 被标识为sass-loader,则另外添加resolve-url-loader。问题是在查看resolve-url-loader 的调试时,它似乎无法从public 文件夹中的scss 文件中解析url。我得到的唯一调试日志如下:

Resolve-url-loader调试日志:

resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./ajax-loader.gif
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.eot
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.woff
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.ttf
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.svg
  ./node_modules/slick-carousel/slick

我在scss 文件中定义了一些在“调试”日志中看不到的url 链接。 我做错了什么?

webpack.config.js详情:

'use strict';

/*some plugins*/
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolatehtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
/*some plugins*/
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const paths = require('./paths');
const modules = require('./modules');
/*some plugins*/

const postcssNormalize = require('postcss-normalize');

const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'true';
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';

const useTypeScript = fs.existsSync(paths.appTsConfig);

const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;

module.exports = function(webpackEnv) 
  const isEnvDevelopment = webpackEnv === 'development';
  const isEnvProduction = webpackEnv === 'production';

  // Webpack uses `publicPath` to determine where the app is being served from.
  // It requires a trailing slash, or the file assets will get an incorrect path.
  // In development, we always serve from the root. This makes config easier.
  const publicPath = isEnvProduction
    ? paths.servedPath
    : isEnvDevelopment && '/';
  const shouldUseRelativeAssetPaths = publicPath === './';

  const publicUrl = isEnvProduction
    ? publicPath.slice(0, -1)
    : isEnvDevelopment && '';
  // Get environment variables to inject into our app.
  const env = getClientEnvironment(publicUrl);

  // common function to get style loaders
  const getStyleLoaders = (cssOptions, preProcessor) => 
    const loaders = [
      isEnvDevelopment && require.resolve('style-loader'),
      isEnvProduction && 
        loader: MiniCssExtractPlugin.loader,
        options: shouldUseRelativeAssetPaths ?  publicPath: '../../'  : ,
      ,
      
        loader: require.resolve('css-loader'),
        options: cssOptions,
      ,
      
        loader: require.resolve('postcss-loader'),
        options: 
          ident: 'postcss',
          plugins: () => [
            require('postcss-flexbugs-fixes'),
            require('postcss-preset-env')(
              autoprefixer: 
                flexbox: 'no-2009',
              ,
              stage: 3,
            ),
            postcssNormalize(),
          ],
          sourceMap: isEnvProduction && shouldUseSourceMap,
        ,
      ,
    ].filter(Boolean);
    if (preProcessor) 
        if (preProcessor === "sass-loader") 
            loaders.push(
                loader: require.resolve('resolve-url-loader'),
                options: cssOptions,
            )
        

      loaders.push(
        loader: require.resolve(preProcessor),
        options: 
          sourceMap: isEnvProduction && shouldUseSourceMap,
        ,
      );
    
    return loaders;
  ;

  return 
    mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
    bail: isEnvProduction,
    devtool: isEnvProduction
      ? shouldUseSourceMap
        ? 'source-map'
        : false
      : isEnvDevelopment && 'cheap-module-source-map',
    entry: [/*...*/].filter(Boolean),
    output: /*...*/,
    optimization: /*...*/,
    resolve: /*...*/,
    resolveLoader: /*...*/,
    module: 
    strictExportPresence: true,
    rules: [
         parser:  requireEnsure: false  ,

        
          /*es-lint loader*/
        ,
        
          oneOf: [
            
              test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
              loader: require.resolve('url-loader'),
              options: 
                limit: 10000,
                name: 'static/media/[name].[hash:8].[ext]',
              ,
            ,
            /*babel-loader*/,
        ,
        /*babel-loader*/,
        
              test: cssRegex,
              exclude: cssModuleRegex,
              use: getStyleLoaders(
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
              ),
              sideEffects: true,
        ,
        
              test: cssModuleRegex,
              use: getStyleLoaders(
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
                modules: true,
                getLocalIdent: getCSSModuleLocalIdent,
              ),
        ,
        
              test: sassRegex,
              exclude: sassModuleRegex,
              use: getStyleLoaders(
                
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                ,
                'sass-loader'
              ),
              sideEffects: true,
        ,
        
              test: sassModuleRegex,
              use: getStyleLoaders(
                
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  modules: true,
                  getLocalIdent: getCSSModuleLocalIdent,
                ,
                'sass-loader'
              ),
        ,
        
              loader: require.resolve('file-loader'),
              exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
              options: 
                name: 'static/media/[name].[hash:8].[ext]',
              ,
        ,
      ],
    ,
    plugins: [/*...*/].filter(Boolean),
    node: /*...*/,
    performance: false,
  ;
;

【问题讨论】:

【参考方案1】:

已解决。原来我必须在 scss 文件中以不同方式定义 url

【讨论】:

不同如何?你能解释一下你是怎么解决的吗?

以上是关于Webpack - resolve-url-loader 无法正确解析路径的主要内容,如果未能解决你的问题,请参考以下文章

【webpack】--config 的使用

# Webpack 学习Webpack 搭建 Vue项目

# Webpack 学习Webpack 搭建 Vue项目

Webpack教程: Webpack安装

初识webpack与webpack环境搭建

初识webpack与webpack环境搭建