159 votes

Comment charger des fichiers image avec webpack fichier-loader

Je suis à l'aide de webpack pour gérer un reactjs projet. Je veux charger des images en javascript par webpack file-loader. Ci-dessous est la 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
        }
    }
}

J'utilise cette ligne pour charger les fichiers images et de les copier à dist/public/répertoire d'icônes et de garder le même nom de fichier.

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

Mais j'ai deux problèmes à l'utiliser. Lorsque j'exécute webpack de commande, le fichier image a été copiée à dist/public/icons/ directory comme prévu. Comment, ver, il a aussi été copiée sur répertoire dist avec ce nom de fichier "df55075baa16f3827a57549950901e90.png".

Ci-dessous mon projet structure: enter image description here

Un autre problème est que j'utilise le code ci-dessous pour importer ce fichier image, mais il ne pouvait pas afficher sur le navigateur. Si je suis en utilisant l'url publique/icons/imageview_item_normal.png' dans la balise img, il fonctionne très bien. Comment utiliser l'objet importé à partir du fichier image?

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%',
  }
}

221voto

omerts Points 3941

Concernant le problème #1

Une fois que vous avez le fichier-chargeur configuré dans le webpack.config, chaque fois que vous utilisez l'importation/l'exigent les tests le chemin à l'encontre de tous les chargeurs, et dans le cas où il y a un match, il passe le contenu par le loader. Dans votre cas, il ne correspondait

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

et donc vous voyez l'image émise à

dist/public/icons/imageview_item_normal.png

qui est le comportement voulu.

La raison pour laquelle vous êtes également obtenir le hash du nom de fichier, c'est parce que vous êtes un ajout d'inline fichier loader. Vous importez l'image:

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

Préfixant avec file!, passe le fichier dans le fichier-chargeur de nouveau, et cette fois, il n'a pas le nom de la configuration.

Afin que votre importation devrait vraiment être juste:

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

Mise à jour

Comme le fait remarquer @cgatian, si vous voulez vraiment utiliser une ligne de fichier loader, ignorant le webpack mondial de configuration, vous pouvez ajouter un préfixe de l'importation avec deux points d'exclamation (!!):

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

Concernant le problème #2

Après l'importation de la png, le img variable que contient le chemin d'accès au fichier-loader "connaît", qui est - public/icons/[name].[ext] (aka "file-loader? name=/public/icons/[name].[ext]"). Votre sortie dir "dist" est inconnu. Vous pouvez résoudre ce de deux façons:

  1. Tout exécuter votre code dans le répertoire "dist"
  2. Ajouter publicPath de la propriété de votre sortie de config, qui pointe vers votre répertoire de sortie (dans votre cas ./dist).

Exemple:

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

18voto

user3717160 Points 91

J'ai eu un problème de télécharger des images vers mon Réagir JS projet. J'ai essayé d'utiliser le fichier loader pour charger les images; j'ai été aussi à l'aide de Babel-loader dans mon réagir.

J'ai utilisé les paramètres suivants dans le webpack:

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

Cela a aidé à charger mes images, mais des images chargées ont été corrompues. Puis, après quelques recherches je suis venu pour savoir que le chargeur a un bug de corruption de la images lors de babel-chargeur est installé.

Donc, pour contourner le problème j'ai essayé d'utiliser l'URL-loader qui a fonctionné parfaitement pour moi.

J'ai mis à jour mon webpack avec les paramètres suivants

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

Ensuite, j'ai utilisé la commande suivante pour importer les images

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

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

8voto

Nalan M Points 834

Installer fichier chargeur tout d’abord :

Et d’ajouter cette règle dans webpack.config.js

6voto

Gaurav Paliwal Points 645

Alternativement, vous pouvez écrire la même chose que

puis utilisez importation simple

``

et en jsx écrire comme``

``sont pour les autres attributs de l’image

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X