• 自己动手封装axios通用方法并上传至私有npm仓库:详细步骤与实现指南


    一、构建方法

    • 确定工具库的需求和功能:在开始构建工具库之前,你需要明确你的工具库需要包含哪些方法及工具,以及这些工具或方法应该具备哪些功能。这有助于你更好地规划你的开发工作。

    • 编写工具代码:使用你熟悉的前端框架(如React、Vue等)编写工具代码。确保你的代码具有良好的可读性和可维护性,并遵循相关的编码规范。

    • 创建工具库的结构:为了组织和管理你的组件,你需要创建一个清晰的目录结构。这可以包括组件的源代码、样式文件、文档和示例等。

    1、api/request.js

    这里是axios操作的封装

    import axios from 'axios'
    import {
        replayDefence,
        encryptRequest,
        distortDefence,
        requestTimeOut
    } from './requestHandler'
    axios.defaults.timeout = requestTimeOut || 20000; //超时响应
    axios.defaults.headers['Content-Type'] = 'application/json;charset=UTF-8'; // 配置请求头
    axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'; // 区分ajax请求还是普通请求
    axios.defaults.withCredentials = true; // axios 默认不发送cookie,需要全局设置true发送cookie
    
    class HttpRequest {
        constructor() {
            this.instance = axios.create()
            this.interceptors()
        }
        interceptors() {
            // request拦截器
            this.instance.interceptors.request.use((config) => {
                if (config.url) {
                    // 防重放
                    replayDefence(config);
                    // 报文加密
                    encryptRequest(config);
                    // 防篡改
                    distortDefence(config);
                    return config;
                }
            }, error => {
                return Promise.reject(error);
            })
    
            // respone拦截器
            this.instance.interceptors.response.use(async (res) => {
                if (res.status === 200) {
                    // return Promise.resolve(res)
                    return res
                } else {
                    return Promise.reject(res)
                }
            }, error => {
                return Promise.reject(error)
            })
        }
    
    
        /**
         * 提交数据,同时支持  data 和 params
         * @param {*} url 
         * @param {*} params 
         * @returns 
         */
        post(url, params = {}) {
            return this.instance({
                url: url,
                method: 'post',
                data: params
            })
        }
    
        /**
         * 获取数据,只支持 params 传参
         * @param {*} url 
         * @param {*} params 
         * @returns 
         */
        get(url, params = {}) {
            return this.instance({
                url: url,
                method: 'get',
                params: params
            })
        }
    
        /**
         * 更新数据,同时支持  data 和 params
         * @param {*} url 
         * @param {*} params 
         * @returns 
         */
        put(url, params = {}) {
            return this.instance({
                url: url,
                method: 'put',
                data: params
            })
        }
    
        /**
         * 删除数据,只支持 params传参
         * @param {*} url 
         * @param {*} params 
         * @returns 
         */
        delete(url, params = {}) {
            return this.instance({
                url: url,
                method: 'delete',
                params: params
            })
        }
    }
    
    export default HttpRequest
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    2、api/requestHandler.js

    这里是请求拦截中的方法的抽离

    const winConfig = window._CONFIG || {}
    const {
        urlRandom,
        tampering,
        SM4Rncrypt,
        timeout
    } = winConfig
    
    export const requestTimeOut = timeout
    
    /**
     * 防重放,这里添加时间戳和6位随机数
     * @param {*} config 
     */
    export const replayDefence = (config) => {
        if (urlRandom && config.url) {
            const nonce = Math.floor(Math.random() * 1000000)
            config.params = {
                _t: Date.parse(new Date()),
                nonce,
                ...config.params
            }
        }
    }
    
    /**
     * 报文加密,这里使用base64代替加密,你可以替换成SM4加密
     * @param {*} config 
     */
    export const encryptRequest = (config) => {
        if (SM4Rncrypt && config.url && config.data) {
            if (['post', 'put', 'delete'].includes(config.method)) {
                config.headers["Content-Type"] = "application/json";
                let jsonStr = JSON.stringify(config.data);
                config.data = btoa(jsonStr);
            }
        }
    }
    
    /**
     * 防篡改,这里是btoa(url+params+btoa(data)),你可以再加盐
     * @param {*} config 
     */
    export const distortDefence = (config) => {
        if (tampering && config.url) {
            let validCode = `${config.url}`
            if (config.params) {
                for (let key in config.params) {
                    validCode += `&${key}=${config.params[key]}`
                }
            }
            if (config.data && config.method != 'get') {
                validCode += SM4Rncrypt ? config.data : JSON.stringify(config.data);
            }
            console.log('validCode:', validCode)
            config.headers["sign"] = btoa(validCode)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    3、api/index.js

    这里文件首页

    import HttpRequest from "./request";
    
    const axios = new HttpRequest()
    
    export default axios
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、测试方法

    编写文档和示例:为你的工具方法编写清晰的文档和示例,这有助于其他开发者理解和使用你的工具库。

    1、api/axios.js

    这个是使用时的文件。现在测试用

    import axios from "./index";
    
    const baseURL = "";
    
    //手机号归属地查询
    export const getPhone = (params) => axios.post(baseURL + '/v2/phone', params)
    
    //历史上的今天
    export const getHistory = (params) => axios.post(baseURL + '/v2/history', params)
    
    // Bing每日壁纸
    export const getBing = (params) => axios.post(baseURL + '/v2/bing', params)
    
    // 用户IP信息
    export const getIp = (params) => axios.post(baseURL + '/v2/getip', params)
    
    //随机颜色
    export const getColor = (params) => axios.get(baseURL + '/v2/color', params)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    2、main.js

    这个是使用时的文件。现在测试用

    import * as api from './api/axios'
    Vue.prototype.$apis = api
    
    • 1
    • 2
    3、app.vue

    这个是使用时的文件。现在测试用

    console.log(this.$apis)
            this.$apis.getPhone({ tel: 13225750729 }).then(res => {
                console.log(res.data)
            })
            this.$apis.getHistory({}).then(res => {
                console.log(res.data)
            })
            this.$apis.getIp({}).then(res => {
                console.log(res.data)
            })
            this.$apis.getColor({}).then(res => {
                console.log(res.data)
            })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    4、vue.config.js

    配置代理

    module.exports = {
      productionSourceMap: false,
      devServer: {
        proxy: 'https://tenapi.cn/'
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    5、index.html

    首页添加全局变量配置信息

    window._CONFIG = {
        urlRandom: true, //防重放
        tampering: true, //防篡改
        SM4Rncrypt: false, //报文加密
        timeout: 10000 //超时时间
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三、打包

    1、配置package.json

    添加打包到库命令

    {
      "scripts": {
        "plugin": "vue-cli-service build --target lib --name zouAxion --dest zouAxion src/api/index.js"
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2、生成库包

    打包工具库:运行打包命令,将你的工具库打包成一个npm包。这通常会在你的项目根目录下生成一个目录,其中包含打包后的文件。

    npm run plugin
    
    • 1

    这是生成的zouAxion文件夹。

    在这里插入图片描述

    3、配置发布信息

    配置package.json:在项目的根目录下创建一个package.json文件,并配置相关的元信息,例如包的名称、版本、描述、入口文件等。确保你的包名在npm上是唯一的,尤其是如果你打算将它发布到公共npm仓库。

    注意:如果你的npm仓库是私有的,你可能需要在package.json中添加一个publishConfig字段来指定你的私有仓库地址。

    在zouAxion文件夹里面创建package.json文件,配置发布信息。

    {
        "name": "zou-axion",
        "version": "0.1.2",
        "private": false,
        "license": "MIT",
        "description": "今天我发布一个zouAxion插件",
        "main": "zouAxion.umd.min.js",
        "scripts": {
          
        },
        "dependencies": {
    
        },
        "devDependencies": {
    
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    4、发布
    • 配置npm仓库:如果你还没有一个私有的npm仓库,你需要先搭建一个。你可以使用Verdaccio等工具来快速搭建一个私有的npm仓库。

    • 配置npm源:在你的本地开发环境中,将npm的源配置为你的私有仓库地址。这可以确保当你发布组件库时,它会被上传到你的私有仓库而不是公共的npm仓库。

    • 登录到npm仓库:在终端中运行npm login命令,并按照提示输入你的npm仓库的用户名、密码和邮箱地址。这将使你能够发布包到你的私有仓库。

    • 发布工具库:在终端中运行npm publish命令来发布你的工具库。这会将你的工具库上传到你的私有npm仓库中。

    配置npm源

    npm set registry http://localhost:4873/
    
    
    • 1
    • 2

    在zouAxion文件夹里面执行发布命令

    npm publish
    
    • 1

    在这里插入图片描述

    四、使用

    一旦你的工具库被发布到私有npm仓库,你就可以在其他项目中使用它了。只需在项目中使用npm install命令来安装你的工具库,然后按照文档中的说明来使用它即可。

    跟使用axios的方法一样。

    1、安装
    npm install axios
    npm install zou-axios
    
    • 1
    • 2

    在这里插入图片描述

    2、使用

    api/axios.js

    import axios from "zou-axios";
    const baseURL = "";
    //历史上的今天
    export const getHistory = (params) => axios.post(baseURL + '/v2/history', params)
    
    • 1
    • 2
    • 3
    • 4

    main.js

    import * as api from './api/axios'
    Vue.prototype.$apis = api
    
    • 1
    • 2

    app.vue

    this.$apis.getHistory({}).then(res => {
        console.log(res.data)
    })
    
    • 1
    • 2
    • 3

    五、维护

    1、维护和更新

    随着项目的进行,你可能需要对你的工具库进行维护和更新。这包括修复bug、添加新功能、更新文档等。在每次更新后,记得重新打包并发布你的工具库,以便其他项目能够使用到最新的版本。

    2、注意事项
    • 版本控制:确保你的工具库使用版本控制(如Git),以便你可以追踪和管理不同版本的代码。

    • 测试:在发布工具库之前,确保进行充分的测试,以确保其稳定性和可用性。

    • 文档和示例:持续更新和维护你的文档和示例,以帮助其他开发者更好地理解和使用你的工具库。

    • 记得在开发过程中保持代码质量和可维护性,并定期更新和维护你的组件库。

  • 相关阅读:
    数据结构-顺序表及其应用
    武义县城区棚户区改造溪南区块安置房建设项目(标段一)电能管理系统的研究及应用
    Python-Requests
    金九银十,收下这份 Java String 面试题
    CSS3-2D缩放
    干货丨应聘Java开发工程师的基本要求是什么?
    谈国产替代---从新出发
    nginx的重写和重定向-你俩究竟是什么关系???
    微信浏览器大字体模式 按钮文字居中用line-height 显示异常
    软件测试工程师的职场发展顺序,月薪30k的测试岗技术要求是真的高...
  • 原文地址:https://blog.csdn.net/shanghai597/article/details/136877825