4

I am having trouble with webpack and react serving static images on webpack dev server.

This is my currenct folder structure

enter image description here

As you can see I have a assets folder witch holds all my images This is my webpack entry and output configuration

enter image description here

Where client entry is source of my react project CLIENT_ENTRY: path.join(process.cwd(), 'src/client/index.jsx')

Now here is my output in BASH when webpack has done its part enter image description here

And here is where I am trying to load images from assets folder in root of the project

enter image description here

Only the import works witch is expected.

I have tried to change the output and public path like so in webpack path: path.resolve(__dirname, 'dist'), publicPath: '/',

path: path.resolve(__dirname, 'dist/assets'), publicPath: '/assets/',

path: path.resolve(__dirname, 'dist'), publicPath: '/assets',

path: path.resolve(__dirname, 'dist'), publicPath: '/assets/',

etc.. etc..

If someone could help me that would be great

jonjonson
  • 263
  • 2
  • 5
  • 16
  • I forgot to mention that in my src/server/server.js I am using express and serving static content like so // Serve static content for the app from the assets directory and build directory app.use(express.static('build')); app.use(express.static('assets')); – jonjonson Mar 20 '17 at 09:08
  • Are they in a relative path to the outputted Main.js? Otherwise it clearly wouldn't work. You can have them in your source and build with with Webpack, if you test for .jpg. I do something like: `{ test: /\.(ttf|otf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?|(jpg|gif)$/, loader: 'file-loader?name=./static/fonts/[name].[ext]' } ` – cbll Mar 20 '17 at 09:08
  • Yes they are like so – jonjonson Mar 20 '17 at 09:10
  • So something like const file = { test: /\.(woff2?|jpe?g|png|gif|ico)$/, use: 'file-loader?name=./assets/images/[name].[ext]' }; – jonjonson Mar 20 '17 at 09:11
  • Something along those lines, yes. Give it a shot and update your javascript to include the relative path of the outputted images and let me know. – cbll Mar 20 '17 at 09:13

3 Answers3

2

In your webpack.config.js, you will need to serve the assets folder as well.

{
  ...webpack,
  devServer: {
    contentBase: [__dirname + '/public', __dirname + '/assets'],
    ...webpack.devServer,
  },
}
Richard
  • 57
  • 7
1

To follow the idea behind webpack you need to process assets from your source to your target.

Therefore, add your images to a relative path in your source (where your entry is, essentially) and add a loader for the images (and perhaps other things) as such:

{
    test: /\.(woff2?|jpe?g|png|gif|ico)$/, 
    use: 'file-loader?name=./assets/images/[name].[ext]'
}

Just update the relative path of the outputs to the assets/images and they should be able to load.

Paul T. Rawkeen
  • 3,994
  • 3
  • 35
  • 51
cbll
  • 6,499
  • 26
  • 74
  • 117
  • 1
    This only works if I import the image. So if I remove for example import test from './test.jpg' then the other image src wont work. Do you know what might be the problem? – jonjonson Mar 20 '17 at 12:19
  • All the other sources worked when the import of test.jpg was there? That sounds strange. – cbll Mar 20 '17 at 12:20
  • No not all only – jonjonson Mar 20 '17 at 12:22
  • It appears test.jpg is the only image in assets/images? – cbll Mar 20 '17 at 12:25
  • Then it makes sense. You look to call it with `{test}` and it's the only valid component there(from what I can see). So if you remove the import, it doesn't render. – cbll Mar 20 '17 at 12:27
  • Yes it dosen't render – jonjonson Mar 20 '17 at 12:30
  • That makes sense, since you removed it. Check out this response: http://stackoverflow.com/questions/32612912/dynamically-add-images-react-webpack – cbll Mar 20 '17 at 12:31
  • 2
    Yes but I want to be able to render from image path because I will get the image path through service. So it has to be like . This will be dynamic not hardcoded images – jonjonson Mar 20 '17 at 12:33
  • By path do you mean locally on the server side, or as a link to some other site? – cbll Mar 20 '17 at 12:34
  • Locally not other site – jonjonson Mar 20 '17 at 12:36
  • Then I don't see an issue with the answer I linked you to above. That should solve it :-) `import test from 'YOUR_PATH/test.jpg';` and call it by `` – cbll Mar 20 '17 at 12:36
  • 1
    Because I will get data from service like user: {name: 'John Smith', imageUrl: 'path/to/my/assets/folder'} and there can be many users it will never be the same image of caurse. So I cant do like import thisUser from 'specific-path.jpg'; Do you understand or is my explanation not good enough? – jonjonson Mar 20 '17 at 12:40
  • 2
    Basically I want to be able to reference images with strings not imports – jonjonson Mar 20 '17 at 12:41
  • I understand it now, but the scope is a bit broader than your initial question. Now you're in the territory of user session and state. You likely have to bind a user property to a specific image and pass it as a props. For this, I suggest making a new question. – cbll Mar 20 '17 at 12:41
  • 1
    No no I have implemented that all. But as I said. The images will be there and the user data logic is already implemented. But the problem is that I cant serve images through my assets folder. So I cant do like That is my only dilemma – jonjonson Mar 20 '17 at 12:49
  • I figured it out. I am the idiot. So I have a devServer.js and a server.js and in the devServer I didn't tell express to server from assets folder I only did it in server.js. Thank for everything though :) – jonjonson Mar 20 '17 at 13:00
0

This is a fix for React(18.1.0) and webpack (5.72.1)

This works for both importing inside a <img src=""/> and <img src={url}/> without having to import or require().

You must first tell Webpack to include images in your dist bundle, I used a file loader for this.

npm install file-loader --save-dev

Then you must set a rule inside your webpack.config.js

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

The structure of my project is:

project-name/
├── public
│   └── index.html
│   └── assets/
│       └── images/
│           └── *.png
├── src/
│   └── components
│       └── filewhereineedtoimport.js
│
├── webpack.config.js
└── package.json

Importing in component

<img src="/assets/images/desired-image.png"/>

My start script inside package.json

"scripts": {
"start": "webpack-dev-server --mode development --open 
 --hot",
"build": "webpack --mode production"
}