React에서 .svg 아이콘 파일 사용하기
Home.js
import IconMenu from "../assets/isvg.svg";
오류 :: import { ReactComponent as IconMenu } from "../assets/isvg.svg";
return <IconMenu fill={"cyan"} width={24} />
중요 declare module ".svg" {}
export default src => export default ReactComponent;
바꿔줌
src를 기본으로 export 하면 fill / width 등 svg 기본 props를 사용할때 타입에러 발생
<IconMenu fill={"cyan"} width={24} />
custom.d.ts
declare module "*.svg" {
import React = require("react");
export const ReactComponent: React.FunctionComponent<
React.SVGProps<SVGSVGElement>
// & { title?: string }
>;
export const src: string;
export default ReactComponent;
}
webpack.config.js
npm install @svgr/webpack
const path = require("path");
// const svgToMiniDataURI = require("mini-svg-data-uri");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// mode: "development",
mode: process.env.NODE_ENV,
devtool: "eval-cheap-source-map",
// Webpack :
// is a tool which can take all the files we have written
// and combine / bundle them into a single.js file
// tell webpack where to start bundling js files
entry: path.join(__dirname, "src", "index.js"),
// tell webpack to create the final bundled file in dist folder in root
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
clean: true,
},
performance: {
// hints: "error",
// maxAssetSize: 51 * 1024,
// maxEntrypointSize: 250 * 1024,
},
// Babel
// is a transpiler so we need to tell it what to transpile.
// configure webpack to use babel
// tell webpack to use babel-loader to transpile(compile) files
// that end with .js
//
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
// test: /\.?js$/,
test: /\.(js|jsx|ts|tsx)/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
// transpiling by using preset
// which is predefined configuration
// that is used to transpile different type to javascript
// to browsers understandable one.
options: {
// preset-env for transpiling ES2015+ syntax
// prset-react for transpiling react code
presets: [
"@babel/preset-env",
"@babel/preset-react",
["@babel/preset-typescript", { allowNamespaces: true }],
],
},
},
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: "asset/resource",
generator: {
publicPath: '/assets/',
outputPath: '/assets/',
},
},
// {
// test: /\.svg/,
// type: "asset/inline",
// generator: {
// dataUrl: (content) => {
// content = content.toString();
// return svgToMiniDataURI(content);
// },
// },
// },
// {
// test: /\.svg$/i,
// type: "asset",
// resourceQuery: /url/, // *.svg?url
// },
{
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
// resourceQuery: { not: [/url/] }, // exclude react component if *.svg?url
use: ["@svgr/webpack"],
},
],
},
// add the bundled js file to the HTML file
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, "public", "index.html"),
minify: true,
}),
],
resolve: {
extensions: [".ts", ".js", ".tsx", ".jsx"],
},
};
.png icon 불러오기
1. import
2. require
위 방법으로 이미지 파일을 컴포넌트안에서 사용하면 빌드시 dist폴더에 파일이 만들어진다.
중요 declare module ".png" {}
jpeg|jpg etc 모두 같은 형태로 모듈을 정의
Home.tsx
import google from "../assets/google.png";
return <>
<img src={require("../assets/cloud.png")} alt="cloud" />
<img src={google} alt="google" />
</>
webpack.config.js
...
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: "asset/resource",
generator: {
publicPath: "http://localhost:3000/assets/",
outputPath: "assets/",
},
},
...
publicPath : build되고 basedUrl + 아이콘 파일 폴더
outputPath : build시 아이콘 파일이 저장되는 폴더
img.src = http://localhost:3000/assets/8518de12373ed3429310.png
형태로 이미지소드 URL을 가짐.