How to import a svg file in React? - reactjs

I have a custom React + Typescript + Webpack project. I need to import a simple .svg file and use it in a component. Typescript claims it:
Cannot find module
I've installed svgr, added it to my webpack config, created a custom.d.ts file allowing svg import in typescript and specified it in the tsconfig.json. Nothing works (I run the component in Storybook for the moment).
Here is my webpack:
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: { loader: "babel-loader" },
},
{ test: /\.css$/, use: ["style-loader", "css-loader"] },
{ test: /\.svg$/, use: ["#svgr/webpack"] },
{ test: /\.(png|svg|jpg|gif)$/, use: ["file-loader"] },
],
},
My component
import React, { useEffect } from "react";
import Account from "./account.svg";
export default function Icon({ icon }) {
return (
<div>
<Account/>
</div>
);
}
The custom.d.ts
declare module "*.svg" {
const content: any;
export default content;
}
// added to tsconfig.json
"include": ["./src/**/*", "./custom.d.ts"],
The svg is a simple <svg><path blabla/></svg> file.
How to fix this?

I had the same problem, and I found the solution here.
I personnaly used this method :
I imported my logo as a ReactComponent.
Then I used it in my code :)
import React from "react";
import { ReactComponent as MySvgFile } from "path/to/file.svg";
export default function MyComponent() {
return (
<div>
<MySvgFile />
</div>
);
}

Related

Style sheet is not styling React Component

I searched for similar problems a lot but couldn't come up with a solution.
I integrated React.js with my working project. I am using Webpack.
Everything runs properly except styling.
I have Style.scss and I import this file in my react file. It compiles without an error but the actual style is not applying to the element.
The inline style works and other classes that are included normally also are fine.
Style.scss
.wtf {
font-weight: bold;
font-size: 40px;
}
Test.js
import React from 'react';
import '../Styles/Style.scss';
const style = {
border: 'solid 5px green'
};
export default class Test extends React.Component {
render() {
return (
<div style={style} className='wtf text-danger'>
Am I React.Component? And I am working too?
</div>
);
};
}
According to the snippet above, text-danger applies color red and border:solid 5px green works too, however, the style is specified in Style.scss is not working.
I checked compiled file and it seems like my scss style code exists there
This is the result in the browser
My webpack.config.js file content is below:
const path = require( 'path' );
module.exports = {
mode: 'development',
entry: {
rooms: './react-src/rooms/rooms.js',
tasks: './react-src/tasks/tasks.js'
},
output: {
filename: '[name].js',
path: path.resolve('../htdocs/react-dist')
},
module: {
rules: [
{
test: /\.scss$/,
use: [
// style-loader
{ loader: 'style-loader' },
// css-loader
{
loader: 'css-loader',
options: {
modules: true
}
},
// sass-loader
{ loader: 'sass-loader' }
]
},
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
}
};
Any idea what is the problem?
Solved
According to my example and my Webpack configuration, it was compiling styles so generating a new class name.
So, that huge token highlighted above is my actual class name which I have to use.
It can be imported as an Object so I can access class name as a property.
This is how it worked.
import React from 'react';
import style from '../Styles/Style.scss';
export default class Test extends React.Component {
render() {
return (
<div className={style.wtf}>
Am I React.Component? And I am working too?
</div>
);
};
}
if you modify your webpack config to:
{...
loader: 'css-loader',
options: {
modules: false
},
...}
you can use regular className property

Module not found: Error: Can't resolve './component/Hello'

I´m trying to import a simple Component but the webpack seems to cant find it. The route is good and the "resolve" in the webpack config is great too, therefore I cant understand where is the issue.
Give it at look please.
By the way, its a Sails/React environment.
ERROR in ./assets/src/component/Hello.jsx 6:12
Module parse failed: Unexpected token (6:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
Hello.jsx:
import React from 'react'
class Hello extends React.Component {
render() {
return(
<div> // Err supposed to be here (line6)
Hello World!
</div>
)
}
}
export default Hello;
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import Hello from './component/Hello'
const App = () => {
return (
<div>
Simple Sails-React stater
<Hello/>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
.babelrc:
{
"presets": ["#babel/env", "#babel/react"]
}
webpack config file:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
entry: './assets/src/index.js'
},
output: {
path: __dirname + '/.tmp/public',
filename: 'bundle.js'
},
module: {
rules: [
{
use: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},
{
use: ['style-loader', 'css-loader'],
test: /\.css$/
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
plugins: [
new HtmlWebpackPlugin({
template: 'assets/src/index.html'
})
]
};
the structure is like this:
-src
--component
----Hello.jsx
--index.js
--index.html
Could you try change extension to Hello.js or change bable-loader test to
test: /\.(js|jsx)$/,

React-Date "SingleDatePicker" not working as expected?

I am using react-dates and trying to implement singledatepicker. All the functionality is working but I dont know why all the default styles are gone. I am also using babel "transform-class-properties"
import React from 'react';
import moment from 'moment'
import 'react-dates/initialize';
import {SingleDatePicker} from 'react-dates';
import 'react-dates/lib/css/_datepicker.css';
const now= moment();
export default class ExpenseForm extends React.Component{
state={
description:'',
note:'',
amount:'',
createdAt:moment(),
calendarFocused:false
}
onDateChange = (createdAt)=>{
this.setState(()=>({createdAt}));
}
onFocusChange =({focused})=>{
this.setState(()=>({calendarFocused:focused}))
}
render(){
return(
<div>
<h3>ExpenseForm</h3>
<form>
<SingleDatePicker
date={this.state.createdAt}
onDateChange={this.onDateChange}
focused={this.state.calendarFocused}
onFocusChange={this.onFocusChange}
/>
</form>
</div>
)
}
}
Here is my Webpack config file and it is loaded with css-loader
const path = require('path');
module.exports = {
entry: './src/app.js',
output: {
path: path.resolve(__dirname, 'public'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},{
test: /\.s?css$/,
use:['style-loader','css-loader','sass-loader']
}
]
},
devtool:'cheap-module-eval-source-map',
devServer:{
contentBase:path.resolve(__dirname, 'public'),
historyApiFallback:true
}
};
I had exact the same problem when integration react-dates into my project, and I believe the root cause is that the css module in your project also compile the css of react-dates which leads to missing of the style. To solve this problem, you could modify the rule in your module like:
...your original css module rule
exclude: [
/node_modules/
]
after applying this rule, you might encounter another issue which is that these css files can't be properly handled due to being excluded, you should then add another css module to handle those css file that you don't want to mess with, for example:
exports.vendorCss = {
test: /\.(css|scss|sass)$/,
include: [/node_modules/],
loaders: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'sass-loader',
},
],
};
and there you have it!! Hope this can help!

Module not found when import .jsx file

I can't find out the solution. I'm using Reactstrap (CSS framework), React, Express, and Webpack.
I was success to import App.jsx file on index.jsx. Then, I tried to import NavbarTemplate.jsx file on App.jsx by using the same way. But, it displayed error like this :
ERROR in ./client/src/components/App.jsx
Module not found: Error: Can't resolve 'NavbarTemplate.jsx' in '/Users/oprent1/v2/oprent-react/client/src/components'
# ./client/src/components/App.jsx 11:22-51
# ./client/src/index.jsx
What is wrong with my configuration ? I have provided several files that related to this below :
webpack.config.js
const path = require('path');
module.exports = {
entry: path.join(__dirname, '/client/src/index.jsx'),
output: {
path: path.join(__dirname, '/client/dist/js'),
filename: 'app.js',
},
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, '/client/src'),
// loader: 'babel',
loader: 'babel-loader',
query: {
presets: ["react", "es2015"],
plugins: ["transform-class-properties"]
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
}
],
},
watch: true
};
index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';
import App from './components/App.jsx'; //SUCCESS when imported
ReactDOM.render(
<App />,
document.getElementById('react-app')
);
App.jsx
import React from 'react';
import NavbarTemplate from 'NavbarTemplate.jsx'; //ERROR when imported
const App = (props) => {
return (
<div>
<NavbarTemplate />
</div>
);
};
export default App;
NavbarTemplate.jsx
import React, { PropTypes } from 'react';
import { Collapse, Navbar, NavbarToggler, NavbarBrand, Nav, NavItem, NavLink } from 'reactstrap';
class NavbarTemplate extends React.Component {
constructor(props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true
};
}
toggleNavbar() {
this.setState({
collapsed: !this.state.collapsed
});
}
render() {
return (
<div>
<Navbar color="faded" light>
<NavbarToggler onClick={this.toggleNavbar} />
<Collapse className="navbar-toggleable-md" isOpen={!this.state.collapsed}>
<NavbarBrand href="/">reactstrap</NavbarBrand>
<Nav navbar>
<NavItem>
<NavLink href="/components/">Components</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://github.com/reactstrap/reactstrap">Github</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>
</div>
);
}
}
export default NavbarTemplate;
Folder Structure
according with webpack can't find module if file named jsx if you don't want to add .jsx on your import you could add resolve: { extensions: ['.js', '.jsx'] } to your webpack.config.
// ...
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, '/client/src'),
// loader: 'babel',
loader: 'babel-loader',
query: {
presets: ["react", "es2015"],
plugins: ["transform-class-properties"]
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
}
]
},
resolve: {
extensions: ['.js', '.jsx']
}
// ...
To import files in the same folder you have to use
./nameOfTheFile
Instead of
nameOfTheFile
So your important statement would be
import NavbarTemplate from './NavbarTemplate.jsx';
if your App.jsx and NavbarTemplate.jsx are in the same root directory then just try
import NavbarTemplate from './NavbarTemplate';
it should work
so basically . represents the parent folder when you try to do something in cmd also.so doing ./NavbarTemplate will resolve your issue as you are importing module from the same folder
If you are using a JSX file extension, you need to import like below code,
import NavbarTemplate from './NavbarTemplate.jsx';
If you are using a JS file extension, you need to import like below code,
import NavbarTemplate from './NavbarTemplate';

React component doesn't import font awesome less/css file

I am trying to use react-fontawesome in my application. Below is my react component class:
import React from 'react'
import 'font-awesome/less/font-awesome.less'
import FA from 'react-fontawesome'
export default class SearchField extends React.Component {
render() {
return (<div className={this.props.className.length===0?'search-field':this.props.className}>
<p>{this.props.text}</p>
<FA name='twitter' />
</div>)
}
}
I have imported the font-awesome.less but the icon doesn't show on the browser. I can see the classname has been set on the dom but there is no css style associated with the dom. I also tried to import the css file as below but it still doesn't work.
import 'font-awesome/css/font-awesome.min.css'
what wrong with my code?
Make sure you have an less loader for webpack:
module: {
loaders: [
{ test: /\.less?$/, loaders: ['style', 'css', 'less'] }
]
}
You might even need to load the icons (fonts) like:
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }

Resources