简体中文
简体中文
English
注册
登录开发者平台
解决方案
行业解决方案
提供从智慧客房、智慧前台到智慧运营等酒店全场景品牌赋能,推进酒店行业数智化变革
一站式智慧照明系统解决方案,赋能企业快速实现人因照明、节能减排的智能化照明升级
综合应用智能化信息,令楼宇具有智慧和生命力,提供投资合理、安全高效、舒适便利的使用空间
快速实现数字化智慧办公空间,有效实现企业增效、降本和节能。
为连锁型品牌商业门店提供完善的管理系统, 提升门店效率
提供从租控授权、租务运营到园区管理等全方位租住解决方案,驱动租住行业智慧转型
融合全屋智能、地产社区等行业场景能力,提供居住空间丰富的产品矩阵和智能体验
IoT 助力校园场景智能化转型, 提升管理效率
全方位赋能开发者实现多场景智慧节能管理解决方案
以 IoT 平台助力中小制造企业, 实现降本、提质、增效
借助丰富硬件生态,一站式构建安全可靠私有化智能平台
为你的业务场景提供全面的 AI 服务及 AI Copilot 开发方案
海量成熟方案,超低研发门槛,极速落地产品智能化
开发者
与志同道合的开发者和专家共同交流
从初创企业到全球领先企业,涂鸦开发者平台协助实现客户成功。
快速获取并体验优秀的开发者案例产品
服务与支持
生态合作
成为涂鸦服务商,接入涂鸦的另一个选择,帮助更多开发者更快实现智能化
智能互联标识
携手开发者生态合作伙伴联合创新,持续创造互联互通商业价值
聚焦产业变革, 推动人工智能产业发展
智联万物,商者无界
信任中心
信任源于透明
我们严格遵守全球信息安全标准
我们严格遵守全球法规要求
您的数据始终由您掌控
诚邀安全业界同仁共同打造和维护物联网健康生态
支持
提供产品智能化开发全链路的常见问答
7×24一对一客服咨询
技术指导、故障修复以及问题解决
关于我们
全球 AI 云平台服务提供商
探索涂鸦的故事
了解涂鸦的全球视野
涂鸦智能-产品解决方案|行业解决方案|全球智能化平台
涂鸦诚聘全球精英
前端SDK开发技巧浅析
形状
1447

图片110图片110

类型检查和智能提示。

作为SDK,我们的目标是减少用户查看文档的时间,所以我们需要提供一些类型的检查和智能提示。一般来说,我们的做法是提供Jsdoc。大多数编辑器可以提供快速生成Jsdoc的方法。我们常用的vscode可以使用documenthis。

图片

另一种方法是使用Flow或Typescript。选择Typescript的主要原因是自动生成的Jsdoc比较原始,我们还需要在上面编辑,所以Jsdoc的维护和代码开发是分开的,代码更新往往会发生,Jsdoc忘记更新。

此外,在开发过程中,我们无法享受SDK开发的类型检查等重要特征。Typescript可以减少我们的错误和调试时间。另一方面,本次开发的SDK在提供时会进行相对简单的压缩,以确保引入后的体积,因此我们希望压缩Jsdoc,Typescript可以将declaration设置为true单独的d.ts文件,通过tsconfig。json。

提示SDK:

图片

最后,对于开发学生来说,强烈建议使用vscode提供//@ts-check注释,即使不使用typescript,也会通过一些类型的推导来检查代码的正确性,可以减少开发过程中的很多bug。

还有一个小技巧。如果您使用的图书馆没有提供智能提示,您可以通过NPM/yarn-D安装@types/{pkgname},这样您就可以在开发过程中享受vscode提供的智能提示,而-D安装在devdependencies中不会增加构建时的代码体积。

接口

既然提到了TypeScript,就提一下TypeScript的语法。基本类型不需要重复,ES6现在可以支持一些以前的高级语法。这里有一些常用但JavaScript开发者不习惯的语法。

很多人人开始使用Typescript时,他们会痴迷于使用any或默认any。建议在开发过程中打开tsconfig中的strict和noimplicany,以确保尽可能少地使用any。你知道,滥用any意味着你的类型检查没有实质性效果。

对于一些暂时无法确定内容的对象类型,可以使用{[key:string]:any},而不是直接使用any。这个接口可以在后期慢慢扩展,直到any完全消除。同时,typescript的类型支持继承。在开发过程中,接口可以拆卸,重复定义可以通过组合继承减少。

然而,接口也会带来一个小痛点。目前,vscode的智能提醒不能与接口很好地对应。当您输入相应的变量时,虽然它将是明亮的,但它只是一个定义名称的接口。没有办法直接看到接口中定义了什么。但当您输入接口中定义的key部分时,vscode会给您一个完整的key提示。虽然这对开发过程有点不友好,但vscode开发团队表示,这是他们故意设计的,因此一些必要的(重要的)参数可以直接用于API参数的基本类型,并将一些配置放入定义为接口的对象中。

枚举

您在代码中使用过:

constplatform=

ios:0,

android:1。

}

那你应该在Typescript中使用枚举:

enumplatform

ios,

android}

这样,在函数中,您可以为参数设置类型为number,然后将其传输到platformios。这样,枚举可以增加代码的维护性。它可以使用智能提示来确保您的正确输入,并且不再有魔法(magicnumber)。与对象相比,它确保了输入类型(您定义的对象可能有一天不再只是number类型的value),不再需要额外的类型判断。

装饰器

事实上,许多开发人员对装饰器既熟悉又陌生。如今,随着redux和mobx的流行,装饰器的调用在代码中很常见,但大多数开发人员并不习惯将其代码逻辑抽取成装饰器。

例如,在SDK的开发中,我们需要提供一些facade来兼容不同的平台(iOS、android或web),而facade将允许开发人员以插件的形式注册。SDK将保持注入对象。传统的使用方法是在使用函数后判断环境,然后判断对象中是否有任何插件,然后使用插件。

事实上,插件是一个拦截器,我们只需要阻止真正的函数运行,一般逻辑是:

exportunctionfacade(env:number){

returnfunction(

target:object,

name:string,

descriptor:Typedpropertydescriptor。

){

letoriginalmethod=descriptor.value;

letmethod;

return

...descriptor,

value(...args:any[]

let[arg]=args;

let{param,success,failure,polyfil}=arg;//这部分可以自定义。

if(method=polyfill[env])

method.use(param,success,failure);

return;

}

originalmethod.apply(this,args);

}

};

};

}

SDK开发过程中经常遇到的另一件事是对许多参数的验证和重新包装,我们也可以用装饰器来完成:

exportunctionsnakeParam(

target:object,

name:string,

descriptor:Typedpropertydescriptor。

){

letcalback=descriptor.value!

return

...descriptor,

value(...args:any[]

let[arg...other]=args;

arg=convertobjectname(arg,convertnamemode.tosnake);

calback.apply(this,[arg...other]);

}

};

}

泛形

最简单的例子是,泛形可以根据用户的输入来确定输出。

(arg:T)

returnarg;

}

当然,它没有什么特别的意义,但它表明返回是基于arg的类型。在一般的开发过程中,你无法逃脱Promise或前面的TypedPropertyDescriptor,这需要类型的内部输入。不要急于使用any。如果您的后端返回类似于标准结构:

exporterfaceire

status:number;

string;

data:object;

}

然后可以这样使用Promise:

functionexample():Promise{

...

}

当然,泛形有很多先进的应用比如泛形约束,泛形创建工厂函数,已经超出了本文的范围,可以去官方文档了解。

构建

如果你的构建工具是Webpack,在SDK的开发中,尽量使用node调用(即webpack.run执行),因为SDK的构建往往会应对很多不同的参数变化。与纯配置相比,node方法可以更灵活地调整输入输出参数,也可以考虑使用rollup。rollup的构建代码更面向编程。

需要注意的是,ES6模块化可以用来构建webpack3和rollup的构建,这样在将业务代码引入您的SDK后,最终业务代码的体积可以通过解构引入来减少。如果您只提供commonjs包,则构建工具的treesharking无法生效。如果使用babel,请注意关闭module的编译。

另一种减少单包体积的方法是利用lerna在git仓库建立多个NPM包,比拆除仓库更方便使用公共部分代码,但也需要注意修改公共部分代码,不影响其他包。

事实上,对于大多数SDK来说,Webpack3的使用体验与rollup相似,更常用的插件几乎与同名对应。然而,rollup有两个优点。一是rollup的构建更加详细,rollup.rollup接受inputoptions生成bundle,也可以生成sourcemap,write生成output。在这个过程中,我们可以做一些详细的工作。

第二点是rollup。rollup将返回promise,这意味着我们可以使用async编写构建代码,而webpack.run仍然使用回调函数。虽然开发人员可以将其包装成promise,但我个人认为rollup的写作方法更好。

单元测试

上周,我的同事做了一个在线分享。我发现很多学生对单一测试非常感兴趣和困惑。在前端开发中,很难测试涉及UI的业务代码开发订单,但对于SDK来说,单元测试必须是准确的充分条件。当然,事实上,我不喜欢单一测试,因为单一测试通常很无聊,但如果我不单一测试,我肯定会被老司机教育_

一般单测以mocha为测试框架,expect为断言库,使用nyc提供单测报告,一般单测如下:

describe(xxxapitest,function(){///注意,如果要用this调用mocha,不要使用箭头函数。

(6000);

it(xxx,done=>{>

SDK.file。

.chooseImage({

count:10,

cancel:()=>{{>{{{>{}

console.log(选择图片取消-');

}

})

.then(res=>{>{>

console.dir(res);

expect.to.be.an(‘object’);

expect.to.have.keys(ids);

expect(res.ids).to.be.an(array);

expect(res.ids).to.have.length.above(0);

uploadImg(res.ids);

();

});

});

});

同样,你也可以用Typescript写单测。当然,在执行过程中,没有必要编译它。我们可以直接为mocha注册ts-node。具体方法请参考writessfortespescriptswithmochandchai-intypescript!。但是,有一点需要提醒你,在写单测试时,尽量依靠文档而不是智能提示,因为你的代码错误可能会导致你的智能提示错误,你根据错误的智能提示写的单测也必须是。

nock可用于网络请求的模拟,需要在it前加一个beforeeeach方法:

describe(proxy)

()

(http://test.com)

.post(/test1)

.delay(200)

.reply(200,{/body。

test1:1,

2:2。

},{

‘server-id’:‘test’//header。

});

});

...

}

最后,我们可以用npmscript和nyc在mocha前获得我们的单测报告。

在这里,我还提到了Typescript中使用的几个小提示供参考。

小贴士:如何在非发包的情况下向内部库添加声明。

SDK在开发过程中依赖于内部NPM包。为了让NPM支持TypeScript调用,我们有几种方法:

将d.ts文件添加到原包中,然后发布。

发布@types包需要注意的是,NPM不支持@types/@scope]/{pkgname}如果是私库包,可以用@types/scope_{pkgname}。

本次使用的标注文件夹存储相应的d.ts文件,适用于开发。如果你认为你写的d.ts不够完美,或者这个d.ts文件目前只需要这个SDK,可以这样使用,在tsconfig.json中修改:

“baseUrl”:

“paths”:

”:[/type/]

}

提示:如何处理不同类型的resolve和rejectpromise回调?

默认情况下,reject返回的参数类型为any,可能无法满足我们的需求。这里有一个解决方案,不是最好的,作为抛砖引玉:

interfaceIPromis

then(

onfulfilled:

|(value:T)=>Tresult1|Promiselike)

|undefined。

|null,,

:

|(reason:U)=>Tresult2|Promiselike)

|undefined。

|null

):IPromise;

(catch(

:

|(reason:U)=>Tresult|Promiselike)

|undefined。

|null):Promise;

免责声明:凡注明来源的文章均转自其它平台,目的在于传递有价值的AIoT内容资讯,并不代表本站观点及立场。若有侵权或异议,请联系我们处理。
即刻开启您的物联网之旅
即刻开启 您的物联网之旅
遇到问题了么?联系专属客户经理在线解答