web-dev-qa-db-fra.com

Comment charger des fichiers image avec webpack file-loader

J'utilise webpack pour gérer un projet reactjs . Je veux charger des images en javascript avec webpack file-loader. Ci-dessous se trouve le 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 des fichiers image, les copier dans le répertoire dist/public/icons et conserver 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 pour l'utiliser. Lorsque j'exécute la commande webpack, le fichier image a été copié dans le répertoire dist/public/icons/ comme prévu. Il a également été copié dans le répertoire dist avec le nom de fichier "df55075baa16f3827a57549950901e90.png".

Voici la structure de mon projet: enter image description here

Un autre problème est que j'utilise le code ci-dessous pour importer ce fichier image, mais il n'a pas pu apparaître sur le navigateur. Si j'utilise l'URL 'public/icons/imageview_item_normal.png' sur la balise img, cela fonctionne correctement. Comment utiliser l'objet importé 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%',
  }
}
119
Zhao Yi

Concernant le problème n ° 1

Une fois que le chargeur de fichiers est configuré dans le fichier webpack.config, chaque fois que vous utilisez import/exigez-le, le chemin est comparé à tous les chargeurs et, le cas échéant, il transmet le contenu à travers ce chargeur. Dans votre cas, cela 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

quel est le comportement recherché.

La raison pour laquelle vous obtenez également le nom du fichier de hachage est que vous ajoutez un chargeur de fichiers en ligne supplémentaire. Vous importez l'image en tant que:

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

Si vous préfixez file!, le fichier passe à nouveau dans le chargeur de fichiers et cette fois, il n’a pas le nom de configuration.

Donc, votre importation devrait vraiment être:

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

Mise à jour

Comme indiqué par @cgatian, si vous souhaitez réellement utiliser un chargeur de fichiers intégré, en ignorant la configuration globale du webpack, vous pouvez préfixer l'importation avec deux points d'exclamation (!!):

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

Concernant le problème n ° 2

Après avoir importé le png, la variable img ne contient que le chemin que le chargeur de fichiers "connaît", qui est public/icons/[name].[ext] (ou "file-loader? name=/public/icons/[name].[ext]"). Votre répertoire de sortie "dist" est inconnu. Vous pouvez résoudre ce problème de deux manières:

  1. Exécutez tout votre code sous le dossier "dist"
  2. Ajoutez la propriété publicPath à votre config de sortie, qui pointe vers votre répertoire de sortie (dans votre cas, ./dist).

Exemple:

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

Un problème est survenu lors du téléchargement des images sur mon projet React JS. J'essayais d'utiliser le chargeur de fichiers pour charger les images; J'utilisais aussi Babel-loader dans ma réaction.

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 les images chargées étaient en quelque sorte corrompues. Après quelques recherches, je me suis rendu compte que le chargeur de fichiers avait un bogue dans la corruption des images lorsque babel-loader est installé.

Par conséquent, pour contourner le problème, j'ai essayé d'utiliser le chargeur d'URL qui fonctionnait parfaitement pour moi.

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

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

J'ai ensuite 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>
12
user3717160

Sinon, vous pouvez écrire le même comme

{
    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'
        }
    }
}

puis utilisez une importation simple

import varName from 'relative path';

et en jsx écris comme <img src={varName} ..../>

.... sont pour d'autres attributs d'image

2
Gaurav Paliwal

Installez d'abord le chargeur de fichiers:

$ npm install file-loader --save-dev

Et ajoutez cette règle dans webpack.config.js

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