How to load image files with webpack file-loader

I am using webpack to manage a reactjs project. I want to load images in javascript by webpack file-loader. Below is the 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

}

}

}

I use this line to load image files and copy them to dist/public/icons directory and keep the same file name.

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

But I have two problems on using it. When I run webpack command, the image file was copied to dist/public/icons/ directory as expected. How, ver it was also copied to dist directory with this file name "df55075baa16f3827a57549950901e90.png".

Below is my project structure:

enter image description here

Another problem is that I use below code to import this image file but it couldn't show on the browser. If I am using url 'public/icons/imageview_item_normal.png' on the img tag, it works fine. How to use the object imported from the image file?

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

}

}

Answer

Regarding problem #1

Once you have the file-loader configured in the webpack.config, whenever you use import/require it tests the path against all loaders, and in case there is a match it passes the contents through that loader. In your case, it matched

{

test: /.(jpe?g|png|gif|svg)$/i,

loader: "file-loader?name=/public/icons/[name].[ext]"

}

and therefore you see the image emitted to

dist/public/icons/imageview_item_normal.png

which is the wanted behavior.

The reason you are also getting the hash file name, is because you are adding an additional inline file-loader. You are importing the image as:

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

Prefixing with file!, passes the file into the file-loader again, and this time it doesn't have the name configuration.

So your import should really just be:

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

Update

As noted by @cgatian, if you actually want to use an inline file-loader, ignoring the webpack global configuration, you can prefix the import with two exclamation marks (!!):

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

Regarding problem #2

After importing the png, the img variable only holds the path the file-loader "knows about", which is public/icons/[name].[ext] (aka "file-loader? name=/public/icons/[name].[ext]"). Your output dir "dist" is unknown.

You could solve this in two ways:

  1. Run all your code under the "dist" folder
  2. Add publicPath property to your output config, that points to your output directory (in your case ./dist).

Example:

output: {

path: PATHS.build,

filename: 'app.bundle.js',

publicPath: PATHS.build

},

以上是 How to load image files with webpack file-loader 的全部内容, 来源链接: utcz.com/a/23860.html

回到顶部