如何从0设计开发一款JS-SDK

news2025/4/1 0:18:11

一、前言

前端SDK是什么?前端SDK是为了帮助前端实现特定需求,而向开发者暴露的一些JS-API的集合,规范的SDK包括若干API实现、说明文档等

前端SDK其实很常见了,比如:

UI组件库:通过封装一系列组件,通过配置帮助开发者调用

  • Antd
  • ElementUI

JS类库:通过实现一类常用的方法,便于开发处理数据,也不用再考虑兼容性

  • lodash
  • moment

监控统计工具:通过API,来监听前端系统的报错、统计数据

  • Sentry
  • 百度统计等

二、开发前的设计

SDK开发其实很简单,简单到写一个函数导出就行,但在实际应用的过程中,我们要考虑很多实际情况。

1、设计原则

满足一类功能的需要

SDK一般都是为了满足一类业务的需要,所以设计之初要明确业务范围

最小可用性原则

即能用确定的方法实现,就不要再去搞复杂的内容。我理解,比如获取DOM,如果GetElementById可以实现,就不要再设计一下GetElementsByTagName、 document.querySelector等方法封装,除非有其他的开发需要无法满足。

最少依赖原则

SDK减少依赖,要避免Lodash、JQuery、Moment、Dayjs等库,尽可能自行实现必要的方法,或者引入尽量小的库。否则会导致SDK打包后过大,或者更新版本带来的兼容问题

当然一切都要根据实际情况,有些SDK是时间的各种处理,自己处理时间的成本太高,不妨引入小型的Dayjs时间库

足够稳定、向后兼容

减少BreakChange,绝不能导致载体应用崩溃,同时做好文档说明

易扩展

模块化实现方法,尽量小的封装函数,保持函数功能的单一性原则,这样就可以更好的增加SDK的能力。

根据这些原则,下面是我们做的对应操作:

2、要实现的功能

首先要明确我们写的SDK是用来做什么的?

比如我本次实现的是用户H5页面的一键登录和号码检测。

那么我们需要暴露两个实例,供其他开发者使用,为了满足易扩展的原则,我们将声明两个类,来实现(如果每个实例都很多能力,可以拆分成两个SDK也是可以的)

3、构建工具和技术选择

提供的SDK一般都要提供压缩和未压缩版本,未压缩可以用来帮助开发调用,查找问题。压缩版本可以使用在生产环境,减少http损耗。所以我们要借助构建工具来集成这部分的能力。

可供选择的压缩工具有很多:webpack、Rollup、Gulp

如果是纯类库的压缩,当然是Rollup更好,压缩更彻底

如果是有DOM和样式,那么使用webpack功能更强大

这里由于我们可能涉及到页面SDK,而且对Webpack更熟悉,所以选择Webpack

4、单元测试

SDK的设计原则有一条:足够稳定、向后兼容,最少依赖原则。

这就意味着我们要少写Bug,所以一定要引入单元测试,这里我们选择Jest,使用起来也很简单。

describe('common test', () => {
    test('osIsPc', () => {
        expect(osIsPc()).toBeBoolean(true, false);
    })
    test("isWifi", () => {
        expect(isWifi()).toBeBoolean(true, false);
    })
})

5、SDK支持的引入方式

浏览器js模块化常见的几种方式包括:amd\cmd\es6 modules\umd

1、静态资源引入

<scriptsrc="/sdk/v1/phoneserver"></script>

2、支持amd引入

define([jquery.js, lodash.js], function($, _){
    console.log("jquery and lodash", $, _)
})

3、支持cmd引入

 define(function(require){
        const lodash = require('./a.js')
        console.log("lodash", lodash)
    })

4、支持es6引入

import { PhoneServer } from'phone-server-sdk'

我们直接在webpack中配置umd方式打包,然后就可以支持上面的多种引入方式

output: {
        path: path.resolve(__dirname, '../dist'),
        filename: '[name].js',
        library: 'Phone-JS-SDK',
        libraryTarget: 'umd'
    }

打包的库命名:Phone-JS-SDK

6、版本维护和更新

  • 管理好版本号
  • 记录好更新日志

SDK版本更新,每个版本都会存在差异,而用户使用的版本肯定也太一样,所以记录好版本更新日志可以减少非技术问题。

通过静态文件导出的SDK要同时部署多个版本,不能随时下线老版本。

7、其他的注意点

  • 代码混淆

  • 开发环境配置和代码格式

  • 上传NPM

  • CDN部署

  • 依赖的三方库如何打包进SDK

  • 仅支持静态引入的库如何处理

  • 如何全局共享库方法

  • 针对有后端API交互的SDK,需要考虑

  • API要限流、限制次数、防止盗刷

  • 日志监控和数据上报

三、项目实践

1、项目需要实现的能力

  • 构建工具构建,配置开发环境、ts配置
  • 实现类库的相关方法(版本记录、帮助命令等)
  • 实现一键登录的方法(预期的功能方法)
  • 实现号码检测的方法
  • 单元测试
  • 上传npm,支持导入

2、搭建基础架构,配置webpack。

我们选择了ts,首先配置下tsconfig.json,然后配置webpack,引入ts-lodader,通过webpack-merge自行配置生产环境和开发环境,比较简单就不重复了

module.exports = {
        entry: {
            sdk: [path.resolve(__dirname, '../src/index.ts')]
        },
        resolve: {
            extensions: ['.tsx', '.ts', '.js'],
        },
        output: {
            path: path.resolve(__dirname, '../dist'),
            filename: '[name].js',
            library: 'SDK',
            libraryTarget: 'umd'
        },
        module: {
          rules: [
            {
              test: /.ts?$/,
              exclude: /node_modules/,
              use: [
                  {
                    loader: 'babel-loader',
                    options: {
                      presets: ['@babel/preset-env'],
                    },
                  },
                  {
                    loader: 'ts-loader',
                    options: {
                      compilerOptions: {
                        noEmit: false,
                      },
                    },
                  },
                ],
            },
          ]
        }

3、实现类库的相关方法

下面是项目的主要目录结构

  • src源代码
  • scripts 是webpack的相关配置
  • public 是用来调试和打包的目录
  • tests 单元测试

LibInfo.ts 用来实现库的一些方法,比如获取版本号,帮助文档,展示依赖版本等

PhoneNumberLogin.ts 一键登录类

PhoneNumberAuth.ts 号码认证类

ajax.ts 简单封装的ajax请求

index.ts 作为入口文件

js-sdk                   
├─ __tests__                                       
│  └─ utils                     
│     ├─ ajax.test.js           
│     └─ commont.test.js                      
├─ public                       
│  ├─ index.html                
│  └─ sdk.js                    
├─ scripts                                     
│  ├─ webpack.base.config.js    
│  ├─ webpack.dev.config.js     
│  └─ webpack.prod.config.js    
├─ src                          
│  ├─ lib                       
│  │  ├─ LibInfo.ts             
│  │  ├─ PhoneNumberAuth.ts     
│  │  ├─ PhoneNumberLogin.ts    
│  │  └─ Init.ts                
│  ├─ utils                             
│  │  ├─ ajax.ts                
│  │  ├─ common.ts                       
│  │  └─ interface.ts           
│  └─ index.ts                  
├─ Readme.md                    
├─ index.d.ts                   
├─ jest.config.js               
├─ package.json                 
├─ tsconfig.json                          
└─ yarn.lock 

4、实现SDK的接口

1、在调用之前,我们需要引用第三方库,而且是md5加密的(如下),无法直接下载本地使用,所以考虑直接插入head中
在这里插入图片描述

exportconst scriptInit = (src: string, callback?: Function) => {
        const script:any = document.createElement('script'),
            fn = callback || function(){};
        script.type = 'text/javascript';
        //IE
        if(script.readyState){
            script.onreadystatechange = function(){
                if( script.readyState == 'loaded' || script.readyState == 'complete' ){
                    script.onreadystatechange = null;
                    fn();
                }
            };
        }else{
            //其他浏览器
            script.onload = function(){
                fn();
            };
        }
        script.src = src;
        document.getElementsByTagName('head')[0].appendChild(script);
    }

2、我们以实现意见登录号码为例,新建PhoneNumberLogin.ts

   const loginPhoneUrl = `http://test.com`
    exportclass PhoneNumberLogin {
        constructor(options:AppInfo){
            this.Init()
        }
        private Init(){
            // 引入第三方依赖的script
            scriptInit(loginPhoneUrl)
        } 
        // 处理一键登录的接口逻辑
        public LoginApp(options){
            return options
        }
    }

这样我们每一个小的功能点都放在一个类中,不对外的设置为私有方法,对外的可以设置为公共方法,其他的通过引用就可以让SDK保持良好的可扩展性。

3、在index.ts中抛出方法

 export * from'./lib/PhoneNumberLogin.ts'

4、在项目中使用

script导入,一般都需要申请域名,那么就需要考虑容灾,防止一台机器挂掉,服务不可用,一般考虑CDN部署

const { PhoneNumberLogin } = Phone-JS-SDK
const PhoneServer = new PhoneNumberLogin()

ES6 Modules导入

 const { PhoneNumberLogin } from"Phone-JS-SDK"
const PhoneServer = new PhoneNumberLogin()

5、上传NPM
接着我们发布下npm,一个JS-SDK就完成了。

登陆npm仓库,没有的话去注册一个,地址[2]

npm login
选择一个中意的SDK名字,查一下是否存在,这里我们起个名字Phone-JS-SDK

执行npm version patch && npm publish --registry=https://registry.npmjs.org,然后就发布成功了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2322781.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux实现rsync+sersync实时数据备份

1.概述 rsync(Remote Sync) 是一个Unix/linux系统下的文件同步和传输工具 2.端口和运行模式 tcp/873 采用C/S模式&#xff08;客户端/服务器模式&#xff09; 3.特点 可以镜像保存整个目录和文件第一次全量备份(备份全部的文件),之后是增量备份(只备份变化的文件) 4. 数…

【计算机网络】计算机网络协议、接口与服务全面解析——结合生活化案例与图文详解

协议、接口与服务 导读一、协议1.1 定义1.2 组成 二、接口三、服务3.1 定义3.2 服务与协议的区别3.3 分类3.3.1 面向连接服务于无连接服务3.3.2 可靠服务和不可靠服务3.3.3 有应答服务和无应答服务 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;…

51c自动驾驶~合集26

我自己的原文哦~ https://blog.51cto.com/whaosoft/11968755 #大模型/Sora/世界模型之间是什么关系 1 什么是大模型 人工智能大模型&#xff08;Artificial Intelligence Large Model&#xff0c;简称AI大模型&#xff09;是指具有庞大的参数规模和复杂程度的机器学习模…

【NUUO 摄像头】(弱口令登录漏洞)

漏洞简介&#xff1a;NUUO 是NUUO公司的一款小型网络硬盘录像机设备。 NUUO NVRMini2 3.0.8及之前版本中存在后门调试文件。远程攻击者可通过向后门文件handle_site_config.php发送特定的请求利用该漏洞执行任意命令。 1.Fofa搜索语句&#xff1a; 在Fofa网站&#xff0c;搜索&…

【设计模式】抽象工厂模式(含与工厂方法模式的对比)

本期我们来学习一下设计模式之抽象工厂模式&#xff0c;在软件开发中&#xff0c;工厂模式 和 抽象工厂模式 都用于创建对象&#xff0c;但它们的应用场景和实现方式有所不同。本文将基于 C 代码&#xff0c;分析抽象工厂模式的实现&#xff0c;并对比其与工厂方法模式的区别。…

IDEA转战Trae AI IED配置

Trae Ai 的前身是vscode IDEA转战Trae AI IED配置 1.安装java相关的插件 2、安装spring相关的插件 3.配置maven环境 打开 Trae AI IDE -> 首选项 -> 设置 -> Editor 设置 ⚠️配置方式有两种 setting.json文件中直接编辑&#xff08;推荐&#xff09;界面设置 方案…

再学:区块链基础与合约初探 EVM与GAS机制

目录 1.区块链是什么 2.remix ​3.账户​ ​4.以太坊三种交易​ 5.EVM 6.以太坊客户端节点 ​7.Gas费用 8.区块链浏览器 1.区块链是什么 只需要检验根节点 Merkel根是否有更改&#xff0c;就不用检查每个交易是否有更改。方便很多。 2.remix 3.账户 如果交易失败的话&…

Nextjs15 - middleware的使用

nextjs 官方文档&#xff08;current branch 对应如下文档&#xff09; Middlewarepath-to-regexp 本专栏内容均可在Github&#xff1a;test_05/Middleware 找到 一、middleware 基本使用 中间件允许您在请求完成之前运行代码。然后&#xff0c;根据传入的请求&#xff0c;您…

边缘计算 vs. 云计算,谁才是工业物联网的未来?

前言 在物联网&#xff08;IoT&#xff09;飞速发展的今天&#xff0c;边缘计算正在彻底改变数据的处理、存储和分析方式。传统的IoT设备数据通常需要发送到云端进行处理&#xff0c;但随着设备数量的激增&#xff0c;这种模式在延迟、带宽和安全性方面暴露出诸多局限。边缘计…

leetcode.189.轮转数组

第一次全反转&#xff0c;第二次反转前k个&#xff0c;第三次反转后n-k个 需要注意的是向又轮转k个时&#xff0c;如果超出数组长度&#xff0c;要对其进行取模运算才是正确的向右轮转个数 class Solution { private:void rotate(vector<int>& nums,int start,int …

OCR 识别案例

OCR 识别案例 注意点&#xff1a;输入图像尺寸比例尽量和参与模型训练的数据集比例相似&#xff0c;识别效果会更好。 1、pytesseract Pytesseract是一个Python的光学字符识别&#xff08;OCR&#xff09;工具&#xff0c;它作为Tesseract OCR引擎的封装&#xff0c;允许你在…

Mybatis配置文件解析(详细)

引言 在了解Mybatis如何帮助客户进行数据的存取后&#xff0c;便对Mybatis的配置文件起了兴趣&#xff0c;在查阅官方文档后&#xff0c;总结了平时能用到的配置&#xff0c;希望能对大家有帮助 1.核心配置文件 主要是指Mybatis-config.xml中 其包含了会深深影响Mybatis行为…

【BFS】《单源、多源 BFS:图搜索算法的双生力量》

文章目录 前言单源BFS例题一、迷宫中离入口最近的出口二、 最小基因变化三、单词接龙四、为高尔夫比赛砍树 多源BFS例题一、 01 矩阵二、飞地的数量三、地图中的最高点四、地图分析 结语 前言 什么是单源、多源BFS算法问题呢&#xff1f; BFS&#xff08;Breadth - First Sear…

【2025】基于springboot+vue的医院在线问诊系统设计与实现(源码、万字文档、图文修改、调试答疑)

基于Spring Boot Vue的医院在线问诊系统设计与实现功能结构图如下&#xff1a; 课题背景 随着互联网技术的飞速发展和人们生活水平的不断提高&#xff0c;传统医疗模式面临着诸多挑战&#xff0c;如患者就医排队时间长、医疗资源分配不均、医生工作压力大等。同时&#xff0c;…

STM32基础教程——PWM驱动舵机

目录 前言 技术实现 原理图 接线图 代码实现 内容要点 PWM基本结构 开启外设时钟 配置GPIO端口 配置时基单元 初始化输出比较单元 调整PWM占空比 输出比较通道重映射 舵机角度设置 实验结果 问题记录 前言 舵机&#xff08;Servo&#xff09;是一种位置&#xff…

odata 搜索帮助

参考如下链接&#xff1a; FIORI ELement list report 细节开发&#xff0c;设置过滤器&#xff0c;搜索帮助object page跳转等_fiori element label 变量-CSDN博客 注&#xff1a;odata搜索帮助可以直接将值带出来&#xff0c;而不需要进行任何的重定义 搜索帮助metedata配置…

Docker基本命令VS Code远程连接

Docker基本命令 创建自己的docker容器&#xff1a;docker run --net host --name Container_name --gpus all --shm-size 1t -it -v Your_Path:Your_Dir mllm:mac /bin/bashdocker run&#xff1a;用于创建并启动一个新容器-name&#xff1a;为当前新建的容器命名-gpus&#x…

大疆上云api直播功能如何实现

概述 流媒体服务器作为直播画面的中转站,它接收推流端的相机画面,同时拉流端找它获取相机的画面。整个流程如下: 在流媒体服务器上创建流媒体应用(app),一个流媒体服务器上面可以创建多个流媒体应用约定推拉流的地址。假设流媒体服务器工作在1935端口上面,假设创建的流…

理解文字识别:一文读懂OCR商业化产品的算法逻辑

文字识别是一项“历久弥新”的技术。早在上世纪初&#xff0c;工程师们就开始尝试使用当时有限的硬件设备扫描并识别微缩胶片、纸张上的字符。随着时代和技术的发展&#xff0c;人们在日常生活中使用的电子设备不断更新换代&#xff0c;文字识别的需求成为一项必备的技术基础&a…

使用 Cursor、MCP 和 Figma 实现工程化项目自动化,提升高达 200% 效率

直接上手不多说其他的&#xff01; 一、准备动作 1、Cursor下载安卓 1.1访问官方网站 打开您的网络浏览器&#xff0c;访问 Cursor 的官方网站&#xff1a;https://www.cursor.com/cn 1.2开始下载: 点击"Download for free" 根据您的浏览器设置&#xff0c;会自…