Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to load images using Webpack file-loader

Tags:

According to the file-loader usage documentation I should be able to load images like:

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

And later via:

import img from './file.png';

Here is my webpack.config.js:

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

module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|jpg|gif)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {}
                    }
                ]
            },
            {
                test: /\.glsl$/,
                loader: 'webpack-glsl-loader'
            },
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.ts$/,
                enforce: 'pre',
                loader: 'tslint-loader',
                options: { failOnHint: true }
            }
        ]
    },
    resolve: {
        extensions: [".tsx", ".ts", ".js"]
    },
    entry: {
        app: './src/index.ts'
    },
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './dist'
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: 'Output Manager'
        })
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/'
    }
};

This is how I am creating my dev-server:

const app = express();

const compiler = webpack(webpackConfig);

app.use(webpackDevMiddleware(compiler, {
    publicPath: webpackConfig.output.publicPath,
}));

app.listen(3000, () => {
    console.log('Listening on port 3000!\n');
});

Further my src structure is something like this:

src
|-images
| |- image.gif
|
|-app.ts

I am tryinbg to load the image in the app.ts as follows:

import img from './images/image.gif';

// ...

private loadImage(): void {
    const image = new Image();
    image.src = img;
    image.onload = () => {

    };
}

Unfortunately I get:

GET http://localhost:8080/undefined 404 (Not Found)

In Chrome's dev-tools navigator I can see the image file under webpack://./src/images/image.gif. The contents look like this:

module.exports = __webpack_public_path__ + "9b626fa0956bfa785b543ef53e895d5e.gif";


//////////////////
// WEBPACK FOOTER
// ./src/images/image.gif
// module id = 109
// module chunks = 0

Also if I hover the img variable while debugging I can see the name string "/9b626fa0956bfa785b543ef53e895d5e.gif". Logging the variable returns undefined though and the image.onload is never triggered.

If I call http://localhost:8080/9b626fa0956bfa785b543ef53e895d5e.gif in the browser I can see the image.

Any idea why I am unable to load the image although I can see it in the browser and the path string seems to be there?

Edit #1:

As I am using TypeScript I had to declare a module in order to import .gif files:

declare module "*.gif" {
  const content: any;
  export default content;
}

Then I found this Github issue where the fix for the issue was to import the file like import * as styles from "styles.scss". So I tried to import like:

import * as img from './images/img.gif';

Unfortunately this results in:

error TS2322: Type 'typeof "*.gif"' is not assignable to type 'string'.

like image 409
チーズパン Avatar asked Dec 17 '17 15:12

チーズパン


1 Answers

I see two issues here. First you should try to load your image file like import * as img from './images/img.gif';. You also have to use the image somewhere in order to actually load it. Importing alone does not trigger loading the file. But a simple console.log(img); should trigger it.

The second issue is the reason why you get this exception:

error TS2322: Type 'typeof "*.gif"' is not assignable to type 'string'.

You should try and wrap the actual usage of the imported file like:

if (typeof img === 'string') {
    console.log(img);
}

This way the exception will not be triggered.

I hope this helps.

like image 69
indexoutofbounds Avatar answered Sep 22 '22 12:09

indexoutofbounds