Reputation: 31526
I am trying to import an image (SVG) into my typescript application
import * as logo from './images/logo';
export default class App extends React.Component<{}, {}>{
render() {
return (
<div className="App">
<header className="App-Header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-tite">Welcome to React</h1>
</header>
</div>
);
}
}
but typescript still throws the error
ERROR in [at-loader] ./src/App.tsx:3:24
TS2307: Cannot find module './images/logo'.
I have a directory called images in the same location as App.tsx and it does have a logo.svg. In my webpack.config.js I also have a entry
resolve: {
extensions: [".js", ".tsx", ".css", ".svg"]
}
I googled and found this thread https://github.com/microsoft/TypeScript-React-Starter/issues/12
But I don't know where to put globals.d.ts
file (as recommended in the last post)
Also why is importing a simple image so hard?
Here is my repo
https://github.com/abhsrivastava/redux-tutorial
Upvotes: 1
Views: 4702
Reputation: 121
If you are writing a typescript application, I suggest you use the microbundle package bundler make configurations easier. Microbundle is a “zero-configuration bundler for tiny modules".It’s a wrapper around rollup with sane defaults nice outputted size stats, multiple target formats (ES modules, CommonJS, UMD).
If you want to take a look https://github.com/developit/microbundle
--external flag to specify external dependencies
package.json
{
"name": "",
"author": ",
"version": "1.0.0",
"description": "",
"source": "src/index.tsx",
"main": "dist/index.js",
"exports": "./dist/index.modern.js",
"unpkg": "dist/index.umd.js",
"scripts": {
"dev": "microbundle watch --external .*/font/.*,.*/style/.*",
"build": "microbundle"
},
"devDependencies": {
"microbundle": "^0.13.0"
},
"keywords": [],
"license": "ISC"
}
Upvotes: 1
Reputation: 148
There is a couple of things, one of them is that your import is missing the extension, and by default it will try to look for a .ts file. Since you are importing the svg, you should do something like
import Logo from './images/logo.svg';
The other thing is, like you mentioned it yourself, you are missing a definitions file for that logo. You can either, next to logo.svg
, create a logo.svg.d.ts
or somewhere in your application create the globals.d.ts
(it can be any name, any location)
Keep in mind that if you declare the module wrong, it will still not find it
The safest way is declare module '*.svg';
inside the global definitions file
Upvotes: 1
Reputation: 42516
One way of easily importing inline SVG files would be to make use of this package called svg-inline-react, which wraps your SVG into a component.
You can try installing it
npm i svg-inline-react
And on your component,
import InlineSVG from 'svg-inline-react';
import logo from './images/logo.svg';
export default class App extends React.Component<{}, {}>{
render() {
return (
<div className="App">
<header className="App-Header">
<div className="App-logo" />
<InlineSVG src={logo} />
</div>
<h1 className="App-tite">Welcome to React</h1>
</header>
</div>
);
}
}
In addition, you might need to configure your webpack.config
by adding an additional rule.
module.exports = {
//...
module: {
rules: [
//...
{
test: /\.svg$/,use: 'svg-inline-loader'
}
]
}
};
And then, you might need to declare the typings too.
interface SvgInlineReactProps {
src: string;
raw?: boolean;
element?: string;
}
declare module 'svg-inline-react' {
export default class InlineSVG extends React.Component<SvgInlineReactProps, any> {
}
}
Upvotes: 1