webpack&react项目优化+技巧篇

1,492 阅读2分钟

最近使用webpack+react自定义一套管理后台的框架,这里总结下这个项目中使用到的优化点。

(1)工具包lodash按需加载

方案1:import进来的时候,按需加载
import { debounce } from 'lodash.debounce'//按需加载

方案2:babel-plugin-lodash结合lodash-webpack-plugin配置

(2) 在使用antd时,默认会将所有语言包引进来。这是因为moment引入的缘故,使用下面插件可以,只引入需要的语言包

    new webpack.ContextReplacementPlugin(
        /moment[\\\/]locale$/,
        /^\.\/(zh-cn)$/
    ),

(3) 好用的图片压缩loader,在typePng压缩后,打包时能压缩挺多的

{
    loader: 'image-webpack-loader',
        options: {
                            mozjpeg: {
                                progressive: true,
                                quality: 65
                            },
                            // optipng.enabled: false will disable optipng
                            optipng: {
                                enabled: false,
                            },
                            pngquant: {
                                quality: [0.65, 0.90],
                                speed: 4
                            },
                            gifsicle: {
                                interlaced: false,
                            },
                            // the webp option will enable WEBP
                            webp: {
                                quality: 75
                            }
                        }
},

(4)antd Icon引入全局,期望变成按需引入 需要下载purched-antd-icons插件

    在resolve.alias中配置:

    '@ant-design/icons': 'purched-antd-icons',//使antd按需加载

(5)配置src下第一层目录,resove.alias配置。---技巧篇

/**
 * 所有配置resolve.alias的配置项,目的使得src下第一个目录可以直接通过name去访问
 */
const srcFiles = fs.readdirSync(resolve('src'))
let resolveConfig = {}
srcFiles.forEach((item, key) => {
    resolveConfig[item] = resolve(`src/${item}`)
})

alias: {
            '@': resolve('src'),
            'apis': resolve('src/services/apis'),
            ...resolveConfig
        }

(6)自定义面包屑(根据menu的父子关系) 需要一个配置文件,一个breadCrumb组件

menu.conf.js配置文件


/*
 * @Description: menu默认打开某个父类menu.item设置为active,非第一层的menu.item需要知道父类menu的路径
 * @LastEditTime: 2019-11-05 19:24:40
 */
export const menuPathRelations = {
    '/institude/wallet': {
        name: '钱包管理'
    },
    '/institude/student': {
        name: '学生管理',
        subs: {
            '/institude/student/detail': {
                name: '学生详情',
                // subs: {
                //     '/institude/student/detail/as': {
                //         name: 'as'
                //     }
                // }
            }
        }
    }
}

BreadCrumb组件

/*
 * @Description: 
 * @LastEditTime: 2019-11-06 20:12:07
 */
import { menuPathRelations } from 'config/menu.conf'
import { Link } from 'react-router-dom'
import { Fragment } from 'react'
import PropsType from 'prop-types'
import { Icon } from 'antd'

export class BreadCrumb extends React.Component {
    static propsType = {
        url: PropsType.string
    }
    //递归
    getPath(paths, path) {
        if (!path) return
        if (paths[path]) {
            return <span>{paths[path].name}</span>
        }
        for (let key in paths) {
            let path_item = paths[key]
            if (path_item.subs) {
                if (!!this.getPath(path_item.subs, path)) {
                    return <Fragment>
                        <Link to={key}>{path_item.name}</Link>
                        <a>&nbsp;<Icon type="right" />&nbsp;</a>
                        {this.getPath(path_item.subs, path)}
                    </Fragment>
                }

            }
        }
    }

    render() {
        return (
            <div className='BreadCrumb_container'>
                {this.getPath(menuPathRelations, this.props.url)}
            </div >
        )
    }
}

面包屑引用

import { BreadCrumb } from "layouts/BreadCrumb/BreadCrumb";
//只需传入当前路由即可
<BreadCrumb url={this.props.match.url} />