webpack:url-loader 圖片路徑問題

咱們使用webpack打包項目中,在處理圖片路徑時, 最經常使用的loader有兩種, url-loader 和 file-loader。css

咱們在寫項目中引用路徑的時候,填寫的URL是基於咱們開發時的路徑, 可是在webpack打包時, 會將各個模塊打包成一個文件,裏面引用的路徑是相對於入口html文件,並非相對於咱們的原始文件路徑的。loader 能夠解析項目中引入的URL,而且根據配置,把圖片拷貝到相應路徑, 再將打包後的文件中的路徑 替換爲圖像的最終路徑。html

file-loader 和 url-loader 均可以解決這個問題。 可是url-loader會將引入的圖片進行編碼, 咱們引用的時候只須要引入這個文件就能夠訪問圖片了, 能夠大大減小 HTTP請求的次數。react

url-loader 封裝了 file-loader, 但並不依賴他, 因此咱們能夠只須要安裝 url-loader就能夠了。webpack

在使用url-loader時,出現了 路徑引用錯誤的 狀況。web

  1. 問題復現

webpack.prod.js瀏覽器

module.exports = {
    // ...
    rules: [
        // ...
        {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
            // ...
            {
                loader: 'url-loader', //是指定使用的loader和loader的配置參數
                options: {
                    limit:500,  //是把小於500B的文件打成Base64的格式,寫入JS
                    name: 'images/[name]_[hash:7].[ext]',
                }
            }
        ]
        },
        {
            test: /\.(css)$/,
            use: [
                MiniCssExtractPlugin.loader,
                {
                    loader: 'css-loader',
                }
            ]
    ],
}

複製代碼

index.jsbash

import React from 'react';
import ReactDom from 'react-dom';
import './index.scss';
import logo from './logo.png';

ReactDom.render(
    <div>Hello world
        <img src={logo} />
    </div>,
    document.getElementById("root")
);

複製代碼

index.cssapp

#root {
    color: aqua;
    background: url('./logo.png');
};
複製代碼

打包後的 css 文件dom

#root{background:url(images/logo_e179a47.png);color:#0ff}
複製代碼

打包後 的 文件結構svg

── css

│   └── app.9fd7e730df40df61cc5a.css

├── images

│   └── logo_e179a47.png

├── js

│  └── app.382da24eb9c30ee2.js

└── index.html

咱們在瀏覽器中打開打包後的 index.html

能夠看出咱們在index.js 中 引入的圖片是能夠正常加載的, 可是咱們在css中引入的背景圖 並無加載成功。

  1. 問題緣由

webpack 在 打包時, 首先會把圖片 複製到 /dist/images/ 文件夾下, 而後把 css 文件中的url 路徑 替換爲webpack中options的name屬性指向的路徑,即 /images/logo.png, 可是這個路徑是相對路徑,是相對於 /dist/css/~.css 來講的, 因此此處引用的 文件地址爲: /dist/css/images/logo.jpg。 可是咱們打包後的css 文件夾中, 並無 images/logo.png, 因此圖片並無渲染出來。 可是 對於 咱們 index.js 中 引用的圖片, 此處相對路徑是相對於 index.html 來講的, 因此 是能夠取到圖片的。

  1. 解決方式
{
    test: /\.(css)$/,
    use: [
        {
            loader: MiniCssExtractPlugin.loader,
            options: {
                publicPath: '../',
            }
        },
        {
            loader: 'css-loader',
        }
    ]
},
複製代碼

在爲css文件配置 loader時, 添加 publicPath 屬性。 這樣作, 咱們在圖片打包時, 仍會將圖片複製在 /dist/images/ 文件夾之下, 可是 在css文件中引用時, 會將路徑替換爲 publicPath + name。

打包後的 css 文件:

#root{background:url(../images/logo_e179a47.png);color:#0ff}
複製代碼

至此, 項目中 css 的文件引用路徑 和 js 中的文件引用路徑 均爲正確的圖片路徑。

相關文章
相關標籤/搜索