4

I've deployed my react application build in Webpack in netlify. I see the CSS, Fonts and everything else loading fine, but not the images under assets/images folder.

Here's my folder structure in live site source path:

enter image description here

my webpack.config.js:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: ['./src/index.js', '@babel/polyfill'],
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-react', '@babel/preset-env'],
                    },
                },
            },
            {
                test: /\.css$/i,
                exclude: /node_modules/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                        },
                    },
                ],
            },
            {
                test: /\.(gif|png|jpe?g)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            // name: '[name].[ext]',
                            // name: '[path][name].[hash].[ext]',
                            name: '/src/assets/images/[hash].[ext]',
                            // outputPath: 'src/assets/images/',
                        },
                    },
                ],
            },
            
        ],
        
    },
    devServer: {
        host: '192.168.1.10', //your ip address,
        historyApiFallback: true,
        contentBase: './build',
        disableHostCheck: true,
    },
    resolve: {
        extensions: ['*', '.js', '.jsx'],
    },
    output: {
        path: path.resolve(__dirname, '/dist'),
        filename: 'bundle.js',
        publicPath: '/',
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            inject: true,
            template: path.resolve(__dirname, 'index.html'),
        }),
    ],
    devServer: {
        contentBase: './build',
        hot: true,
    },
};

And I try to access my images in JSX like this -

import { HeaderLogo } from '../../assets/images/image_name.png';

When I inspect element and change in path from /assets/images/image-name.png to /src/assets/images/image-name.png it is showing image in live site.

enter image description here

Here's my folder structure in local:

enter image description here

The same is working fine in local. Not sure what causing issue in prod. I know something is wrong with my file-loader path. But not sure where to correct.

Any suggestions please?

beta programmers
  • 513
  • 2
  • 8
  • 23
  • Your configuration looks fine. Are you deploying static files only in your server? – tmhao2005 Aug 06 '20 at 02:24
  • If I get you correct, I added all image files in the src/assets/images and build it. And I'm accessing images from there, not from any other server. In the ./dist folder generated, I see the assets. But not when deployed over netlify – beta programmers Aug 06 '20 at 02:37
  • I meant are you serving your website at `dist/index.html` in your server? Which means the server root is `dist` directory so as you request to the asset with public path would be okay like `yourDomain/assets/image/logo.png`. – tmhao2005 Aug 06 '20 at 02:46
  • Yes, I see the site is served from dist/index.html. But, I don't want to change all the images src path to yourDomain/assets/image/logo.png, which is a pain process. I doubt if something's working with same path in local, would some change in config make this work in prod? Or everytime I deploy, should I change it to public path? – beta programmers Aug 06 '20 at 02:53
  • publicPath is useful as you deploy your assets on cdn. Plugins also ref to this value as it generates assets in your html file. Anyway can I get to know the url where your code has been deployed so I'd like to see how your image assets are being appended in html index file? – tmhao2005 Aug 06 '20 at 02:58
  • 1
    Here's the site, where I'm facing this issue currently - https://frosty-colden-75f287.netlify.app/#/ – beta programmers Aug 06 '20 at 03:01
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/219308/discussion-between-beta-programmers-and-tmhao2005). – beta programmers Aug 06 '20 at 03:02
  • It looks like your index.html is not in the same dir with dist since I am able to get the image with dist https://frosty-colden-75f287.netlify.app/dist/assets/images/icon_bangles1.png which means they are the same level (dist + index.html) – tmhao2005 Aug 06 '20 at 03:09

1 Answers1

4

You need to copy the image files to the build directory.

To do that, install webpack copy plugin: copy-webpack-plugin

npm install copy-webpack-plugin --save-dev

And webpack config should be:

// import copy plugin
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: ['./src/index.js', '@babel/polyfill'],
    module: {

       ...

    },
    plugins: [

        ...

        new CopyPlugin({
            patterns: [
                {
                    from: path.resolve(__dirname, '/src/assets/images'),
                    to: path.resolve(__dirname, 'dist')
                }
            ]
        }),
     ]
};

For more details https://www.npmjs.com/package/copy-webpack-plugin

Jason Jin
  • 1,739
  • 14
  • 21
  • that didn't solve it either.. I still don't see the assets under dist folder. You can find the latest built project at https://frosty-colden-75f287.netlify.app/#/ – beta programmers Aug 06 '20 at 03:55
  • this is latest config change - output: { path: path.join(__dirname, "/dist"), filename: "bundle.js", publicPath: "/", }, plugins: [ new webpack.HotModuleReplacementPlugin(), new HtmlWebpackPlugin({ template: path.resolve("./dist/index.html"), }), new CopyPlugin({ patterns: [ { from: path.resolve(__dirname, "/src/assets/images"), to: path.resolve(__dirname, "dist"), }, ], }), ], – beta programmers Aug 06 '20 at 03:58
  • Did you figure it out? – Euridice01 Jan 29 '21 at 02:17