Webpack网址加载程序或文件加载程序无法正常运行反应应用程序

时间:2019-10-03 02:38:03

标签: reactjs nginx webpack webpack-4 webpack-file-loader

使用Webpack 4或url-loader或file-loader不能在浏览器中加载图像。小图片不在数据url中(或者如果它们是浏览器,则不会显示它们),并且文件加载器也不会发出文件网络请求。

Nginx在https://{server}/images/image_name.png处正确地提供了图像,但在https://{server}处没有提供图像,并且没有在网络检查器网络面板中进行图像的网络调用。

到目前为止,最好的猜测是Webpack URL加载器或文件加载器一定不能生成正确的URL。在app.bundle.js中搜索URL时找不到主机。我已经尝试了publicPathoutputPath等的每一种组合的几天。从所有其他stackoverflow帖子中,什么都没有。

除了搜索js之外,还有什么方法可以查看webpack生成的url吗? webpack配置不正确吗?故障排除建议?

这是我在代码中处理图片的方式:

import nav_logo from "Images/white_nav_logo.svg";

<img src={nav_logo} />

这是我的webpack.common.js:

module.exports = {
  mode: mode,
  entry: {
    app: ["./src/js/app.js"]
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: '[name].bundle.js',
    publicPath: '/',
    chunkFilename: '[name].bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.(sc|c|)ss$/,
        issuer: {
          exclude: /\.less$/,
        },
        use: [
          {
            loader:  'style-loader',
            options: {
            },
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              localIdentName: '[name]-[local]-[hash:base64:5]',
            },
          },
        ],
      },

      {
        test: /\.less$/,
        use: [
          {
            loader:  'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            },
          },
        ],
      },
      {
        test: /\.(jsx?)/,
        exclude: ["/node_modules", "/src/js/elm"],
        use: [
          { loader: "babel-loader?cacheDirectory=true",
          }
        ]
      },
      {
        test: /\.scss$/,
        issuer: /\.less$/,
        use: {
          loader: './src/js/sassVarsToLess.js'
        }
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: 'images/[name].[ext]',
            }
          },
          {
            loader: "image-webpack-loader",
            options: {
              disable: true,
              mozjpeg: {
               progressive: true,
               quality: 65
              },
              // optipng.enabled: false will disable optipng
              optipng: {
               enabled: true,
              },
              pngquant: {
               quality: '65-90',
               speed: 4
              },
              gifsicle: {
               interlaced: false,
              },
              // the webp option will enable WEBP
              webp: {
               quality: 75
              }
            }
          },
        ],
      },
      {
        test: /\.(ttf|otf|eot|woff2?)$/,
        loader: "file-loader",
        options: {
          name: 'fonts/[name].[ext]',
        }
      }
    ],
    noParse: [/\.elm$/]
  },
  node: {
    fs: 'empty'
  },
  plugins: [
    new Dotenv(),
    new CopyWebpackPlugin([{
      from: "./src/assets/css",
      to: "css"
    },
  ]),
  ]
};

和webpack.prod.js

module.exports = merge(common, {
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.(sc|c|)ss$/,
        issuer: {
          exclude: /\.less$/,
        },
        use: [
          {
            loader:  MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              localIdentName: '[name]-[local]-[hash:base64:5]',
            },
          },
        ],
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            }
          },
        ],
      },
      {
        test: /\.(jsx?)/,
        exclude: ["/node_modules", "/src/js/elm"],
        use: [
          { loader: "babel-loader?cacheDirectory=true",
          }
        ]
      },
      {
        test: /\.scss$/,
        issuer: /\.less$/,
        use: {
          loader: './src/js/sassVarsToLess.js' // Change path if necessary
        }
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: 'images/[name]-[hash:8].[ext]'
            }
          },
          {
            loader: "image-webpack-loader",
            options: {
              disable: false,
              mozjpeg: {
               progressive: true,
               quality: 65
              },
              // optipng.enabled: false will disable optipng
              optipng: {
               enabled: true,
              },
              pngquant: {
               quality: '65-90',
               speed: 4
              },
              gifsicle: {
               interlaced: false,
              },
              // the webp option will enable WEBP
              webp: {
               quality: 75
              }
            }
          },
        ],
      },
      {
        test: /\.(ttf|otf|eot|woff2?)$/,
        loader: "file-loader",
        options: {
          name: 'fonts/[name].[ext]',
        }
      }
    ],
    noParse: [/\.elm$/]
  },
  optimization: {
    minimizer: [new TerserJSPlugin(), new OptimizeCSSAssetsPlugin({})]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/assets/prod.index.html'
    }),
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
})

这是nginx default.conf

server {
    listen       80;
    server_name  <domain_name>;
    root /usr/share/nginx/html;
    access_log  /var/log/nginx/host.access.log  main;

    index index.html;

    location / {
      try_files $uri $uri/ =404;
    }

    location /images/ {
      alias /usr/share/nginx/html/images/;
      try_files $uri $uri/ =404;
      error_log /var/log/nginx/error.log debug;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

2 个答案:

答案 0 :(得分:0)

url-loader不会将图像作为单独的文件加载,而是将文件编码为base64格式,并将其包含在js包中。因此,将没有对图像文件的单独请求。看到这个答案: Url-loader vs File-loader Webpack

尝试使用file-loader加载图像。我通常使用file-loader加载字体和图像,并且可以正常工作。

我正在使用此工作配置(开发中):

// this is configured outside of the exported webpack configuration code
const BASE_DIR = resolve(`${__dirname}`);

module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    resolve: {
        modules: [
            resolve(BASE_DIR),
            'node_modules'
        ]
    },
    output: {
        // ...
        publicPath: '/'
    },

    module: {
        rules: [
            // ...
            {
                test: /\.(png|svg|jpg|jpeg|gif|tiff)$/,
                use: [
                    'file-loader?name=assets/[name].[ext]'
                ]
            },
            // ...
        ]
    }
    // ...
}

我的图像文件实际上位于'src / assets / logo_arc.png',并且我以这种方式使用它:

import logo from 'src/assets/logo_arc.png';
// ...
<img src={logo} alt={'company logo'} />

我可以按预期看到我的文件位于子目录assets下的开发构建目录中。

在webopack开发服务器上运行应用程序时(在本地主机上,我的自定义端口9901),图像在地址http://localhost:9901/assets/logo_arc.png上提供。

在开发包中,我可以看到其中涉及的部分:

// definition of webpack public path
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "/";

// ...

// the image itself as a webpack module
/***/ "./src/assets/logo_arc.png":
/*!*********************************!*\
  !*** ./src/assets/logo_arc.png ***!
  \*********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("module.exports = __webpack_require__.p + \"assets/logo_arc.png\";//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2xvZ29fYXJjLnBuZz8wMmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlCQUFpQixxQkFBdUIiLCJmaWxlIjoiLi9zcmMvYXNzZXRzL2xvZ29fYXJjLnBuZy5qcyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3B1YmxpY19wYXRoX18gKyBcImFzc2V0cy9sb2dvX2FyYy5wbmdcIjsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/assets/logo_arc.png\n");

/***/ }),
// importing webpack module into variable, it is used later in the img element
var src_assets_logo_arc_png__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! src/assets/logo_arc.png */ "./src/assets/logo_arc.png");

// ...

// usage in the img element
react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("img", {
        src: src_assets_logo_arc_png__WEBPACK_IMPORTED_MODULE_7___default.a,
        alt: 'company logo'
      }))

答案 1 :(得分:0)

用于使用url-loader加载图像

如果您注意到config/webpack.config.js内部 有一个module object,其中有rules object。 对于提供的规则或规则列表,有限制键 限制键非常重要

极限值的意义 -如果要加载的图像大小大于提供的限制,则默认使用文件加载器。 例如 如果我的配置低于webpack.config.js

{
  test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  loader: require.resolve('url-loader'),
  options: {
             limit: 10000,
             name: 'static/media/[name].[hash:8].[ext]',
           },
},

在我的moudules -> rules object

以上限制值为10000个字节 因此,如果发现图像大小等于或大于10000,则webpack将仅使用大小小于10000字节的url-loader加载那些图像,默认情况下将使用文件加载器,直到未指定后备加载器为止。

因此,假设您要在代码中动态添加类似这样的图片。

import largeimage from '../static/images/largeimage.jpg'或其他任何路径 并且largeimage的大小小于图片的限制值。

解决方案

要使webpack使用url-loader加载图像,您的largeimage大小应小于限制值。

因此,请增加限制或减小图像的大小。

参考 https://webpack.js.org/loaders/url-loader/#limit