Як завантажити файли зображень за допомогою завантажувача файлів webpack


141

Я використовую webpack для управління проектом reactjs . Я хочу завантажити зображення в javascript через webpack 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
        }
    }
}

Цей рядок я використовував для завантаження файлів зображень та копіювання їх у каталог dist / public / icons і зберігав те саме ім’я файлу.

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

Але у мене є дві проблеми при його використанні. Коли я запускаю webpackкоманду, файл зображення було скопійовано у dist / public / значки / каталог, як очікувалося. Однак він також був скопійований у каталог каталогу з цим ім'ям файлу "df55075baa16f3827a57549950901e90.png".

Нижче наведена моя структура проекту: введіть тут опис зображення

Інша проблема полягає в тому, що я використовував код нижче, щоб імпортувати цей файл зображення, але він не відображається у браузері. Якщо я використовую url 'public / icons / imageview_item_normal.png' на тезі img, він працює чудово. Як використовувати об’єкт, імпортований з файлу зображення?

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-завантажувач?
Хайме

Я видалив завантажувач url з файлу конфігурації webpack і видалив каталог dist та повторно запустив команду webpack, проблема все ще існує. Файл створено.
Joey Yi Zhao

Відповіді:


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'

Оновлення

Як зазначає @cgatian, якщо ви дійсно хочете використовувати вбудований завантажувач файлів, ігноруючи глобальну конфігурацію webpack, ви можете встановити імпорт двома знаками оклику (!!):

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

Щодо проблеми №2

Після імпорту png imgзмінна містить лише шлях, про який "знає" завантажувач файлів, який є public/icons/[name].[ext](aka "file-loader? name=/public/icons/[name].[ext]"). Ваш вихідний "dist" невідомий. Ви можете вирішити це двома способами:

  1. Запустіть весь код у папці "dist"
  2. Додайте publicPathвластивість до конфігурації виводу, яка вказує на ваш вихідний каталог (у вашому випадку ./dist).

Приклад:

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

153
ЦЕ Є ТІЛЬКИЙ ДОКУМЕНТ НА ​​ЦІЛЬКІЙ ІНТЕРНЕТ, який говорить, що "publicPath" змінить URL-адресу, яку використовує завантажувач файлів.
Тайлер Джонс

@TylerJones, що ти маєш на увазі?
Сагів бг

1
@ Sag1v, я думаю, що вам краще написати нове запитання, з додатковою інформацією, зокрема про налаштування веб
пакету

1
Просто для додання відповіді. (будь ласка, редагуйте, як я вважаю, що це корисно). Якщо ви опинитесь у ситуації, коли ви хочете обійти конфігурацію require('!!file-loader!wenis.png');
веб-пакету

2
Документація значно покращилась з вищезазначених заявок :) - Дивіться: github.com/webpack-contrib/file-loader#options та більше інформації на publicPath: github.com/webpack-contrib/file-loader#publicpath
Pavelloz

15

У мене виникла проблема з завантаженням зображень до мого проекту React JS. Я намагався використовувати завантажувач файлів для завантаження зображень; Я також використовував навантажувач Babel у своїй реакції.

Я використовував наступні налаштування у веб-пакеті:

{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 завдяки @ gaurav-paliwal. Використання imgPath імпорту допомогло мені вирішити це, і зображення скопійовано у папку dist / build
Ебрагім

1
Цей outputPathключ допоміг мені з’ясувати, де розмістити файли з папками та все це. Інші відповіді тут не спрацювали. Дуже дякую.
Тиеліко

0

webpack.config.js

{
    test: /\.(png|jpe?g|gif)$/i,
    loader: 'file-loader',
    options: {
        name: '[name].[ext]',
    },
}

anyfile.html

<img src={image_name.jpg} />

0

Це мій робочий приклад нашого простого компонента Vue.

<template functional>
    <div v-html="require('!!html-loader!./../svg/logo.svg')"></div>
</template>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.