वेबपैक फ़ाइल-लोडर के साथ छवि फ़ाइलों को कैसे लोड करें


141

मैं उपयोग कर रहा हूँ webpack एक का प्रबंधन करने के reactjs परियोजना। मैं वेबपैक द्वारा जावास्क्रिप्ट में छवियों को लोड करना चाहता हूं file-loader। नीचे webpack.config.js है :

const webpack = require('webpack');
const path = require('path');
const NpmInstallPlugin = require('npm-install-webpack-plugin');

const PATHS = {
    react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
    app: path.join(__dirname, 'src'),
    build: path.join(__dirname, './dist')
};

module.exports = {
    entry: {
        jsx: './app/index.jsx',
    },
    output: {
        path: PATHS.build,
        filename: 'app.bundle.js',
    },
    watch: true,
    devtool: 'eval-source-map',
    relativeUrls: true,
    resolve: {
        extensions: ['', '.js', '.jsx', '.css', '.less'],
        modulesDirectories: ['node_modules'],
        alias: {
            normalize_css: __dirname + '/node_modules/normalize.css/normalize.css',
        }
    },
    module: {
        preLoaders: [

            {
                test: /\.js$/,
                loader: "source-map-loader"
            },
        ],
        loaders: [

            {
                test: /\.html$/,
                loader: 'file?name=[name].[ext]',
            },
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel-loader?presets=es2015',
            },
            {test: /\.css$/, loader: 'style-loader!css-loader'},
            {test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=/public/icons/[name].[ext]"},
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loaders: ['babel-loader?presets=es2015']
            }
        ]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
            },
            output: {
                comments: false,
            },
        }),
        new NpmInstallPlugin({
            save: true // --save
        }),
        new webpack.DefinePlugin({
            "process.env": {
                NODE_ENV: JSON.stringify("production")
            }
        }),
    ],
    devServer: {
        colors: true,
        contentBase: __dirname,
        historyApiFallback: true,
        hot: true,
        inline: true,
        port: 9091,
        progress: true,
        stats: {
            cached: false
        }
    }
}

मैंने इस लाइन का उपयोग छवि फ़ाइलों को लोड करने के लिए और उन्हें डिस्टर्ब / पब्लिक / आइकन डायरेक्टरी में कॉपी करने और उसी फ़ाइल नाम को रखने के लिए किया।

{test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=/public/icons/[name].[ext]"}

लेकिन इसका उपयोग करते समय मुझे दो समस्याएं हैं। जब मैं webpackकमांड चलाता हूं , तो छवि फ़ाइल को डिस्टर्ब / पब्लिक / आइकन / डायरेक्टरी में अपेक्षित रूप से कॉपी किया गया था । हालाँकि इसे इस फ़ाइल नाम "df55075baa16f3827a57549950901e90.png" के साथ डिस्टर्ब डायरेक्टरी में भी कॉपी किया गया था।

नीचे मेरी परियोजना संरचना है: यहां छवि विवरण दर्ज करें

एक और समस्या यह है कि मैंने इस छवि फ़ाइल को आयात करने के लिए नीचे दिए गए कोड का उपयोग किया था लेकिन यह ब्राउज़र पर नहीं दिख रहा है। अगर मैं img टैग पर url 'public / icons / imageview_item_normal.png' का उपयोग कर रहा हूं, तो यह ठीक काम करता है। छवि फ़ाइल से आयातित ऑब्जेक्ट का उपयोग कैसे करें?

import React, {Component} from 'react';
import {render} from 'react-dom';
import img from 'file!../../public/icons/imageview_item_normal.png'

export default class MainComponent extends Component {

  render() {
    return (
      <div style={styles.container}>
        download
        <img src={img}/>
      </div>
    )
  }

}

const styles = {
  container: {
    width: '100%',
    height: '100%',
  }
}

1
क्या आपने url-loader को हटाने की कोशिश की है?
जैम

मैंने वेबपैक कॉन्फ़िगर फ़ाइल से url-लोडर को हटा दिया और डिस्टेंट डायरेक्टरी और रेरन वेबपैक कमांड को हटा दिया, समस्या अभी भी है। फ़ाइल जनरेट की गई थी।
जॉय यी झाओ

जवाबों:


196

समस्या # 1 के बारे में

एक बार जब आप फ़ाइल-लोडर को webpack.config में कॉन्फ़िगर कर लेते हैं, तो जब भी आप आयात का उपयोग करते हैं / इसकी आवश्यकता होती है, तो यह सभी लोडरों के विरुद्ध पथ का परीक्षण करता है, और यदि कोई मैच होता है तो यह उस लोडर के माध्यम से सामग्री को पार करता है। आपके मामले में, यह मेल खाता है

{
    test: /\.(jpe?g|png|gif|svg)$/i, 
    loader: "file-loader?name=/public/icons/[name].[ext]"
}

और इसलिए आप छवि को उत्सर्जित होते देखते हैं

dist/public/icons/imageview_item_normal.png

जो वांछित व्यवहार है।

आपको हैश फ़ाइल नाम भी मिल रहा है, इसका कारण यह है कि आप एक अतिरिक्त इनलाइन फ़ाइल-लोडर जोड़ रहे हैं। आप छवि को इस रूप में आयात कर रहे हैं:

'file!../../public/icons/imageview_item_normal.png'.

के साथ उपसर्ग करना file!, फ़ाइल को फ़ाइल-लोडर में फिर से पास करता है, और इस बार इसका नाम कॉन्फ़िगरेशन नहीं है।

तो आपका आयात वास्तव में सिर्फ होना चाहिए:

import img from '../../public/icons/imageview_item_normal.png'

अपडेट करें

जैसा कि @catatian ने उल्लेख किया है, यदि आप वास्तव में इनलाइन फ़ाइल-लोडर का उपयोग करना चाहते हैं, तो वेबपैक वैश्विक कॉन्फ़िगरेशन को अनदेखा करते हुए, आप आयात को दो विस्मयादिबोधक चिह्न (!!) के साथ उपसर्ग कर सकते हैं!

import '!!file!../../public/icons/imageview_item_normal.png'.

समस्या # 2 के बारे में

पीएनजी आयात करने के बाद, imgचर केवल पथ-लोडर "के बारे में जानता है", जो कि public/icons/[name].[ext](उर्फ "file-loader? name=/public/icons/[name].[ext]") है। आपका आउटपुट dir "dist" अज्ञात है। आप इसे दो तरीकों से हल कर सकते हैं:

  1. "डिस्ट" फ़ोल्डर के तहत अपने सभी कोड को चलाएं
  2. publicPathअपने आउटपुट कॉन्फिग में प्रॉपर्टी जोड़ें , जो आपके आउटपुट डायरेक्टरी (आपके मामले में। / सूची) की ओर इशारा करता है।

उदाहरण:

output: {
  path: PATHS.build,
  filename: 'app.bundle.js',
  publicPath: PATHS.build
},

153
यह केवल उसी इंटरनेट पर मौजूद डॉक्युमेंट है जो कहता है कि "publicPath" फ़ाइल लोडर द्वारा उपयोग किए गए url को बदल देगा।
टायलर जोन्स

@ टायलरजोन का क्या मतलब है?
सागिव बीजी

1
@ Sag1v, मुझे लगता है कि आपके लिए एक नया प्रश्न पोस्ट करना बेहतर है, जिसमें आपके
वेबपैक कॉन्फिगरेशन

1
बस उत्तर में जोड़ना है। (कृपया संपादित करें क्योंकि मुझे लगता है कि यह उपयोगी है) यदि आप अपने आप को ऐसी स्थिति में पाते हैं जहां आप आवश्यकता के बयान पर वेबपैक कॉन्फ़िगरेशन को बायपास करना चाहते हैं तो आप आयात से पहले दो अतिरिक्त बैंग्स जोड़ सकते हैंrequire('!!file-loader!wenis.png');
cgatian

2
उपरोक्त दावों के बाद से दस्तावेज़ में बहुत सुधार हुआ है :) - देखें: github.com/webpack-contrib/file-loader#options और अधिक जानकारी publicPath: github.com/webpack-contrib/file-loader-publicpath
Pavelloz

15

मेरे पास अपने रिएक्ट JS प्रोजेक्ट में चित्र अपलोड करने का एक मुद्दा था। मैं छवियों को लोड करने के लिए फ़ाइल-लोडर का उपयोग करने की कोशिश कर रहा था; मैं भी अपनी प्रतिक्रिया में बैबल-लोडर का उपयोग कर रहा था।

मैंने वेबपैक में निम्नलिखित सेटिंग्स का उपयोग किया है:

{test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=app/images/[name].[ext]"},

इससे मेरी छवियों को लोड करने में मदद मिली, लेकिन लोड की गई छवियाँ एक प्रकार की दूषित थीं। फिर कुछ शोध के बाद मुझे पता चला कि फ़ाइल-लोडर में बैबल-लोडर स्थापित होने पर छवियों को भ्रष्ट करने का एक बग है।

इसलिए, इस मुद्दे के इर्द-गिर्द काम करने के लिए मैंने URL-लोडर का उपयोग करने की कोशिश की, जो मेरे लिए पूरी तरह से काम करता है।

मैंने निम्नलिखित सेटिंग्स के साथ अपने वेबपैक को अपडेट किया

{test: /\.(jpe?g|png|gif|svg)$/i, loader: "url-loader?name=app/images/[name].[ext]"},

फिर मैंने छवियों को आयात करने के लिए निम्न कमांड का उपयोग किया

import img from 'app/images/GM_logo_2.jpg'
<div className="large-8 columns">

      <img  style={{ width: 300, height: 150 }} src={img} />
</div>

6

फ़ाइल लोडर को पहले स्थापित करें:

$ npm install file-loader --save-dev

और इस नियम को webpack.config.js में जोड़ें

           {
                test: /\.(png|jpg|gif)$/,
                use: [{
                    loader: 'file-loader',
                    options: {}
                }]
            }

5

वैकल्पिक रूप से आप जैसा चाहें लिख सकते हैं

{
    test: /\.(svg|png|jpg|jpeg|gif)$/,
    include: 'path of input image directory',
    use: {
        loader: 'file-loader',
        options: {
            name: '[path][name].[ext]',
            outputPath: 'path of output image directory'
        }
    }
}

और फिर साधारण आयात का उपयोग करें

import varName from 'relative path';

और jsx में लिखें <img src={varName} ..../>

.... अन्य छवि विशेषताओं के लिए हैं


1
Jsx धन्यवाद @ गौरव-पालीवाल द्वारा डाली गई छवियों के लिए यह अंतिम भाग बहुत महत्वपूर्ण है। आयात imgPath का उपयोग करने से मुझे इसे हल करने में मदद मिली और छवियों को दूर / बिल्ड फ़ोल्डर में कॉपी किया गया
Ebrahim

1
उस outputPathकुंजी ने मुझे यह पता लगाने में मदद की कि सबफ़ोल्डर्स के साथ फाइल कहां रखी जाए और वह सब। यहाँ अन्य जवाब काम नहीं किया। बहुत बहुत धन्यवाद।
थुलथुला


0

यह हमारे सरल Vue घटक का मेरा काम करने का उदाहरण है।

<template functional>
    <div v-html="require('!!html-loader!./../svg/logo.svg')"></div>
</template>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.