从零开始编写Nest库

十万个为什么

nest库是什么?nest是一个typescript构建的node框架,那nest库可以理解为依赖nest框架的node库?node是一个javascript服务端的运行环境,那又要怎样用typescript编写javascript库呢?做为一只从其他语言(js几乎零基础只会简单的jQuery)转来学习nest的菜鸟刚开始总会在某些时刻冷不丁得被这些概念绕的云里雾里,不过是因为直接跨过jsnodets直接啃nest的原因,底层建筑不牢固直接搬砖终究是雾里看花,而从零手撸一个nest库不妨可以视为一个敲门砖,可以带我们看一探js世界的冰山一角.

撸起袖子开干

给它一个家

nest库终究也是一个独立的项目,和其他开源库一样我们使用github来做版本管理,新建一个空白仓库clone到本地.

1
2
$: git clone https://github.com/tashuo/nestjs-config
$: cd nestjs-config

给它一支指挥棒

npm is the world’s largest software registry. Open source developers from every continent use npm to share and borrow packages, and many organizations use npm to manage private development as well.

本项目使用npm做为js的依赖管理工具

npm使用package.json作为整个项目的配置,包括包名、版本号、依赖、测试等等,当前直接初始化配置文件,初始化过程中可以交互式的填入一些基本配置,也可以一路回车后面手动编辑配置.

1
$: npm init

具体配置可参考:https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html

ts项目需要重点关注maintypes配置,当前项目的场景只需要配置maindist/index.js,因为dist目录编译出的index.d.ts也可用于声明导出的文件

If your package has a main .js file, you will need to indicate the main declaration file in your package.json file as well. Set the types property to point to your bundled declaration file.

Also note that if your main declaration file is named index.d.ts and lives at the root of the package (next to index.js) you do not need to mark the types property, though it is advisable to do so.

告诉它如何变身

TypeScript is a language that is a superset of JavaScript: JS syntax is therefore legal TS.

typescript作为javascript的超集并不能直接运行在浏览器或node运行时中,tsjs封装得连它妈(浏览器、node)都不认识了,要想进门必须把这身皮脱掉,这个活儿由tsc负责,tsc把ts编译为原生的js代码,而说到编译就会涉及到不同的编译参数及配置,tsconfig.json挺身而出.

The presence of a tsconfig.json file in a directory indicates that the directory is the root of a TypeScript project. The tsconfig.json file specifies the root files and the compiler options required to compile the project.

具体配置可参考 https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

告诉它存在的意义

本项目只实现一个简易的nest配置模块,项目启动时自动获取指定config目录的所有配置,这份配置可以在项目任何其他模块使用.

为什么会存在依赖nest的库呢,比如像lodashaxios这些库可以直接在nest中使用,并不依赖于nest(它们在江湖上大杀四方的时候nest还在吃奶吧),那我们要写的这个库可以这么酷吗?不好意思这个头必须得低,因为有求于人,我们要在项目启动时初始化所有配置,而且配置获取的方式也依赖框架(provider),它们那么酷是因为没有包袱,如果你也能对社会对外界对欲望少一些依赖,你也可以这么酷:)

如前文所讲,我们要依赖nest框架的启动来加载配置,需要引入动态模块概念,提供一个ConfigModule用于import,提供一个ConfigService作为Provider供其他模块引入使用,所有代码均在项目的src目录下.

告诉它要靠谱

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.

It works with projects using: Babel, TypeScript, Node, React, Angular, Vue and more!

俗话说得好,没有提供单元测试的代码都是耍花枪,而且编写单元测试时总会时不时得告诉你的代码有多屎,比如现在写的ConfigService无法脱离ConfigModule单独测试,因为constructor依赖了从ConfigModule注入的参数,所以出现了三个单元测试文件的奇观,如果够优雅的话一个文件就可以覆盖所有的测试,后面再优化,下次一定.

单元测试代码在test目录

告诉它做一个对社会有用的人

项目开发完需要发布到公有的npm仓库才可以使用,官方仓库是https://registry.npmjs.org/,国内一般使用淘宝、清华或其他境内的源,在进行发布流程中如果设置了非官方源,需要在下面执行命令时显式指定官方的源(–registry https://registry.npmjs.org)

  1. 编译代码($: tsc)
  2. 注册npm账号(https://www.npmjs.com/)
  3. 登录($: npm login --registry https://registry.npmjs.org))
  4. 发布到远程仓库($: npm publish --registry https://registry.npmjs.org))

需要注意的是,npm直接使用package.json中的name作为全局包名,如果包名已存在就会报错.

本来以为像phpcomposer一样包名会带前缀,起码没那么容易冲突,结果npm这操作整的,会不会很多很屌的包名已经被人恶意占坑了.

仓库

所有的代码都在https://github.com/tashuo/nestjs-config,欢迎提出问题一起交流.