前章见
手动搭webpack + React Hooks + TypeScript + Antd(一)
手动搭webpack + React Hooks + TypeScript + Antd(二)
手动搭webpack + React Hooks + TypeScript + Antd(三)
本章继续svg img 等引入
在src中新建assets文件夹
在Home页面中引入一个png,和引入less一样,webpack不能处理png需要加loader处理
安装 url-loader
yarn add url-loader -D
build/webpack.common.js
module: {
rules: [
...
+ {
+ test: /\.(png|jpe?g|gif)$/i,
+ use: [
+ {
+ loader: 'url-loader',
+ options: {
+ limit: 8192, // 8k 1024为1kb
+ outputPath: 'images', // 打包到images文件夹下
+ },
+ },
+ ],
+ },
...
]
}
还是报错
在types里新建img声明文件img-modules.d.ts
types/img-modules.d.ts
declare module '*.png';
declare module '*.jpg';
declare module '*.jpeg';
declare module '*.gif';
declare module '*.svg';
但是页面中还是不能显示图片,编译还报错了
安装 file-loader
yarn add file-loader -D
图片已经正常显示, npm run build试试
跑起来发现引入错误
直接打开background中的链接
发现打包后的css内图片引用不正确
build/webpack.commom.js 修改option
{
loader: 'url-loader',
options: {
limit: 8192, // 8k 1024为1kb
outputPath: 'images', // 打包到images文件夹下
+ publicPath: '../images'
},
},
build后最后查看打包文件
页面也正确显示
引入SVG
在assets下新建icons文件夹,放入一些svg文件,页面import一个svg文件
+ import peopleCountSvg from '@assets/icons/people-count.svg';
页面报错
所以还是需要处理svg的loader, 此处选择svg-sprite-loader
安装 svg-sprite-loader
yarn add svg-sprite-loader -D
build/webpack.commom.js
module: {
rules: [
...
+ {
+ test: /\.svg$/,
+ include: resolve('../src/assets/icons'),
+ use: [
+ {
+ loader: 'svg-sprite-loader',
+ },
+ ],
+ },
...
]
}
页面引入svg报错
改成,此处id是引入svg的id
<svg>
{React.createElement('use', { href: id, 'xlink:href': id})}
</svg>
页面成功引入
但是报warning
将`xlink:href `改成 `xlinkHref`,然后warning没有了
总结svg引入有两种方式
方式一
<svg>
{React.createElement('use', { href: id, 'xlink:href': id})}
</svg>
方式二(推荐)
<svg>
<use xlinkHref={`#${peopleCountSvg.id}`} />
</svg>
但是每次使用svg都需要引入,所以需要将svg Icon抽出做成组件
使用require.context 引入icons文件夹中所有的icon
参考 一张图带你了解webpack的require.context
src/components/Icon.tsx
有两种方法解决此报错
方法一
const request = (require as any)['context']('@assets/icons', false, /\.svg$/);
方法二(推荐)
需要安装@types/webpack-env (推荐,此处安装@types/webpack-env)报错即解决
安装@types/webpack-env
yarn add @types/webpack-env -D
可以打印request 发现是一个webpack上下文环境
点进去看
在文件夹下删除svg 这里面的map数据会实时删除
src/components/Icon.tsx 最终的Icon组件
import React, { CSSProperties } from 'react';
interface IconProps {
id: string;
width?: number | string;
height?: number | string;
className?: string;
style?: CSSProperties;
}
// 引入所有的icons
const request = require.context("@assets/icons", true, /\.svg$/);
request.keys().map(request);
export default function Icon(props: IconProps) {
const { id, ...reset } = props;
return (
<svg {...reset}>
<use xlinkHref={`#${id}`} />
</svg>
)
}
引用SVG Icon组件
import Icon from '@components/Icon';
<Icon id={'nav-pay'} className={styles.icon} style={{ width: '15px', height: '15px' }}/>