Loading images in React with Webpack - image

I'm having trouble getting a simple image to show up in a simple app using Webpack and React.
I've read this thru and tried a few different ways, but keep getting various errors, or at best sometimes no errors, but also no image displaying.
Here is my React component:
import React from 'react';
import styles from '../css/main.css';
import Menu from './Menu';
const logo = require('./images/PIVX_Planet_1a_239x83.png');
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {test: 'foo'};
}
render() {
return (
<div>
<div id='container'></div>
<div className={styles.logo}>
<img src={logo}/>
</div>
<div>
<Menu/>
</div>
</div>
);
}
}
Here is my webpack config:
...
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
"presets": ["react", "es2015", "stage-0", "react-hmre"]
}
}, {
test: /\.(jpg|png|svg)$/,
loader: 'url-loader',
options: {
limit: 25000,
},
}, {
test: /\.json?$/,
loader: 'json'
}, {
test: /\.css$/,
loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]'
}]
}
...
With this, get error from webpack in console:
ERROR in ./app/components/App.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./images/PIVX_Planet_1a_239x83.png in /Users/mac/_DEV/_LAB/PIVX/PIVX-Planet-2/app/components
# ./app/components/App.js 67:11-56
I've also tried using babel-plugin-transform-react-jsx-img-import
(https://www.npmjs.com/package/babel-plugin-transform-react-jsx-img-import)
And then just use:
<div className={styles.logo}>
<img src="./images/PIVX_Planet_1a_239x83.png"/>
</div>
In that case, there are no errors, but the image show up broken.
I've tried changing the relative path to the image with all these combinations.
Directory structure:
app
components
App.js
images
PIVX_Planet_1a_239x83.png
index.html
...
Any insights?

As per your directory structure the path that you need to use is
const logo = require('../images/PIVX_Planet_1a_239x83.png');
since images is under app directory and not under components from where you are trying to get the image location
Also make sure all your loaders are properly installed

you can also try let as:
let logo = require('../images/PIVX_Planet_1a_239x83.png');
Always use let as much as possible to avoid the scope monster

The problem I was having was using
import logo from './images/PIVX_Planet_1a_239x83.png'
instead of
const logo = require('./images/PIVX_Planet_1a_239x83.png');
in a typescript react app w/ a bespoke webpack config.

I have tried everything that you guys have suggested but nothing is working for me. when I put my code in and 'run dev' it come out with an error placeholder. I am using it in the app.js and would like my logo as a link to the home page or just show up at all, in this case I was attempting to just have it on the page.
import '../styles/globals.css'
import Link from 'next/link'
import bpdlogofull from '../public/bpdlogofull.png'
`function MyApp({ Component, pageProps }) {
return (
<div>
<nav className="border-b p-6">
<img src={bpdlogofull} alt='logo'className='flex justify-end'/>
<div className="flex mt-4">
<Link href="/" className="home-button">

Related

Laravel mix removes subfolder from image path

I've set up an alias for my public folder where I've placed my images.
So they are inside public/images. I have a subfolder for certain types of images - in this case, card brands.
They're in public/images/card-brands
Here is my alias config:
mix.webpackConfig({
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'#': __dirname + '/resources/js',
'#public' : __dirname + '/public'
},
},
})
I'm importing the images in my vue component file:
import amex from '#public/images/card-brands/amex.svg'
import discover from '#public/images/card-brands/discover.svg'
import visa from '#public/images/card-brands/visa.svg'
import mastercard from '#public/images/card-brands/mastercard.svg'
Then using it inside my components data like so:
export default {
name: 'PaymentMethod',
data() {
return {
...
visaSvg: visa,
mastercardSvg: mastercard,
discoverSvg: discover,
amexSvg: amex,
currentCardBrand: this.initialCurrentCardBrand
...
}
},
props: {
...
initialCurrentCardBrand: String,
...
}
computed: {
getCurrentCardBrandSvg() {
switch (this.currentCardBrand) {
case 'mastercard':
return this.mastercardSvg;
break;
case 'visa':
return this.visaSvg;
break;
case 'amex':
return this.amexSvg;
break;
case 'discover':
return this.discoverSvg;
break;
}
}
}
...
Finally, I'm using it on my template as and image src: <img class="w-10" :src="getCurrentCardBrandSvg">
Now, even though the images and my import path are using the card-brands subfolder, the URL that is generated ignores this and just looks for the images in the root images folder.
It should be:
/public/images/card-brands/visa.svg
but it's generating as
/public/images/visa.svg
How can I get it to keep my subfolder?
try this instead {{ asset('/images/card-brands/mastercard.svg')) }}
I faced a similar issue in laravel. I used the above format.Please correct me if Im wrong.
Edit: This could be slightly wrong. It works correctly for importing images via javascript, but I think grabbing images via laravel in blade templates still needs the images in the public folder.
The issue was not knowing that I was supposed to put my images folder inside the resources folder rather than public.
Laravel Mix will compile the images like it does the JS and SCSS and place it in public automatically.
So I created an images folder in resources, deleted my manually made images folder in public, and made an alias:
alias: {
'#images': __dirname + '/resources/images'
}
and now I can link to that inside my vue component.
import amex from '#images/card-brands/amex.svg'
import discover from '#images/card-brands/discover.svg'
import visa from '#images/card-brands/visa.svg'
import mastercard from '#images/card-brands/mastercard.svg'
The generated images will automatically be placed in public on the root level once I run npm run dev or npm run prod

How to load mdboostrap with laravel?

I am trying to install mdbootstrap vue into a Laravel 5.7 project, but i realy don't understand how i suppose to do it.
I did everything like in here but anyway it doesn't work.
On rendering I got such vue error :
Unknown custom element: <mdb-btn> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
Code from view:
<mdb-btn color="elegant">Elegant</mdb-btn>
please follow this steps from this answer https://github.com/mdbootstrap/Vue-Bootstrap-with-Material-Design/issues/1#issuecomment-372342369 :
insert this in your main.js file:
import 'mdbvue/build/css/mdb.css'
import 'mdbvue/src/components/Waves.css'
then in your component import the components that you need:
import { Container, Row, Column, Btn, Card } from 'mdbvue';
for example:
<template>
<mdb-btn-fixed #mouseenter.native="hover" #mouseleave.native="hoverOut"
icon="pencil" size="lg" :bottom="30" :right="25">
<mdb-btn-fixed-item :show="show" color="red" icon="star"/>
<mdb-btn-fixed-item :show="show" color="yellow" icon="user"/>
<mdb-btn-fixed-item :show="show" color="green" icon="envelope"/>
<mdb-btn-fixed-item :show="show" color="blue" icon="shopping-cart"/>
</mdb-btn-fixed>
</template>
<script>
import { mdbBtn, mdbBtnFixed, mdbBtnFixedItem } from 'mdbvue';
export default {
data() {
return {
show: false
};
},
name: 'ButtonPage',
components: {
mdbBtn,
mdbBtnFixed,
mdbBtnFixedItem
},
};
You have a lot of examples of usage here at the bottom: https://mdbootstrap.com/docs/vue/components/buttons/

Getting sass css modules to show up when using enzyme with gatsby

So I'm having issues when I use enzyme to test a component thats using css modules. Or should I say filename.module.scss
Whats happening when I do something like:
const wrapper = shallow(<MyComponent {...data}/>);
console.log('wrapper = ', wrapper.debug());
My debug works and shows my component structure with all my divs in there. The issue is none of my styles are getting added durning running tests. But when I run Gatsby develop the styles are getting added. So just to be clear only in test mode do I not see the styles added to my component!!!
MyComponent.js
import React, { Component } from 'react';
import styles from ‘./MyComponent.module.scss';
class MyComponent extends Component {
render() {
const {
name,
} = this.props;
return (
<React.Fragment>
<div className={styles.header}>
<div className={styles.name}>{name}</div>
</div>
</React.Fragment>
);
}
}
My debug is showing all styles as undefined which is driving me crazy as I can't test based on style name if a div exists.
Here is my package setup for jest.
"jest": {
"moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/.jest/styleMock.js"
},
"setupFiles": [
"<rootDir>/.jest/setupFiles.js"
]
}
For anyone else running into this issue.
npm install identity-obj-proxy
then add this to your package.json
"jest": {
"moduleNameMapper": {
".+\\.(css|styl|sass|scss)$": "identity-obj-proxy"
},
"setupFiles": [
"<rootDir>/.jest/setupFiles.js"
]
}
Hope this helps someone.

JS/(X) import: to import React components?

I want to import a React component from a jsx file in a template and render it in the template with ReactDOM. Later in production I would only want to ship react and all the dependencies of the component only when a site is loaded that has that component.
I have created a React component like this:
editor.jsx
import * as React from "react";
import {Editor} from "draft-js-plugins-editor";
const plugins = [];
export class EditorComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty(),
};
}
onChange(editorState) {
this.setState({
editorState,
});
}
render() {
return (<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={plugins}
/>);
}
}
http://www.phoenixframework.org/docs/static-assets suggests the require syntax for accessing module exports. So I added the following to my template <script>const editor = require("web/static/js/editor").EditorComponent</script>. This does not work though, because the browser cannot interpret require (or brunch does not pick it up).
I configured brunch like so:
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/web\/static\/vendor/],
presets: ["es2015","react"]
}
},
modules: {
autoRequire: {
"js/app.js": ["web/static/js/app"],
"js/editor.jsx": ["web/static/js/editor"]
}
},
I am a bit lost here. How can this be done?
One idea that pops to mind is to create a JS file and import it in the template you want with a <script> tag. In the same template create an empty <div id=editor>. Then, in the JS file import React and ReactDOM and the component you want and use something like this:
ReactDOM.render(
<Editor/>,
document.getElementById("editor")
)
However, I'm not sure I understand your problem correctly.

Cannot retrieve images in my react component

I am quite new at coding so please be indulgent... I searched a lot and I don't manage to get my issue fixed :(
I would like to get my images rendered through and html img tag. I saw that the best way in react is to import my images. Like this :
import avatar from './avatar.png';
export default class Connection extends React.Component {
render () {
return (
<div>
{this.props.user.firstname} {this.props.user.lastname}
<img src={avatar} className='img-circle' />
<a href='#' onClick={this.props.logout}>Déconnexion</a>
</div>
);
}
}
I use the following webpack config to load these images :
module: {
loaders: [
{ test: /\.jsx?$/, exclude: [/node_modules/], loader: 'babel' },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader') },
{ test: /\.(png|gif|jpe?g|svg|jpg)$/i, loader: 'file-loader?hash=sha512&digest=hex&name=[path][name]-[hash].[ext]' },
{ test: /\.(png|gif|jpe?g|svg|jpg)$/i, loader: 'url-loader?limit=10000' }
]
}
I see that webpack manage to load the jpg or png files but when it comes to display it, it seems that the file generated/copied is not available (ex: /MyApp/avatar-50b93a2df8aec266d7c8c1c0f5719d1b.png is not available).
I use the webpack dev server so I don't see my files bundled and the dist or build folder created.
Any idea of solving my issue ?
Thanks,
When using the require within the img tag I get the following error :
Module not found: Error: Cannot resolve 'file' or 'directory' ./avatar
I tried to get the extension in the webpack config but it does not solve anything :(
Here is my public path config in my webpack config :
output: {
path: path.join(__dirname, '/build'),
publicPath: '/',
filename: 'bundle.js'
}
To load images with Webpack you need to do:
<img src={require('./avatar.jpg'})/>
Webpack crawls through your application codebase, code gets bundled into a single file however files are not kept in the same structure, by calling require Webpack will do dependency management for you, in this case the file will move around and code will be injected so it is pointing to it's bundled location.
You can take a look at this article from SurviveJS Book. Load Images Chapter

Resources