node+ts的心得与坑 1 @types 2 单元测试 3node中module的导入 4 noImplicitAny , true or false?
首先先明确,用node+ts的目的,为什么不ng+ts。这一点后面还会反复提醒自己 node毕竟不是ng。
用node的理由:
处理js,在后端操纵dom,读写类html格式的东西,比直接用py的后端更舒服。
着眼点还是后端数据处理,作为类似单机版数据库的后台进程db_master(RESTful API等于 数据库的CRUD)。
不需要写界面,不需要web component这些。所以用ts,不意味着,到处都是class。仍然是data居多,function居多。
用ts的理由:
主要理由:给了增加类型注解的选择权,export方式也更贴近es6标准。
不太成立的理由:自己毕竟写过了点ng。ts用着还可以,其实es6本身,经过2015 2016 2017,也很不错了。
用node+ts稍微写点东西,就发现
1 各种库必须自己知道选择,安装。
2 js语言太乱。编码风格,module居然好几套玩法,浏览器端的amd 服务器端的commonjs es6 不要说,还有ts
而且package.json,tsconfig.json往往都要自己修改配置,要知道改这个(习惯cli接口,习惯命令行参数的,会好受些)。
现在就体会到py的好了:果然鱼最难感知的就是水的存在。
1 py有大而全的标准库,30多个主题,我写到今天也不敢保证都用过。保证了开箱即用,不需要这样自己东1个库,西1个库。即使py的标准库往往不是实际中最优的库,但是对上手来说,够用了。单元测试不用必须手动安装pytest,用自带的unittest就基本够用了。
总的感觉是pip库质量比npm高很多。node也就是flask一样的微框架而已。
2 py代码本身风格就很整齐。自从09年2/3代切换之后,就更没什么坑。
记录一些从py开发者角度看遇到的很别扭的坑。
为了ts使用而 npm i @types/XXX,但这个并不能代替XXX本身的安装。
可以理解成@types只是为js库提供了index.d.ts 这样的带有类型注解的导出声明而已。如果js库类似于是.c的话,@types就类似于给加了一个.h文件。
不能代替.c本身。
所以用d3 npm i d3 @types/d3 都要装,其他库同理.
2 单元测试
要用到mocha和chai。
注意, 因为是用ts,所以在package.json里这样写:
"scripts": { "build-ts": "tsc", "start": "ts-node src/server.ts", "start:dev": "nodemon", "serve": "node dist/server.js", "test": "mocha --require ts-node/register test/**/*.ts" },
test得写成这样,注意还用到了ts-node。
测试用例在根目录的test路径下 .ts结尾 测试用例的例子:
import { expect } from 'chai'; import 'mocha';
import {helloworld} from '../src/a.ts'
然后是在vscode里file 首选项,键盘快捷方式里,搜索run test 找到运行全部测试用例。设置一个快捷键。我给了ctrl+alt+t
这样就可以单元测试了。
3node中module的导入
分为2种情况
3.1 第三方库
安装在node_modules里的那些。
因为我是用ts写,所以 npm i XXX @types/XXX 是可以的,
不过在node里用,还是有node版就直接装node版的 d3-node最省事
而且,在tsconfig,json里因为"module":是 "commonjs",
{ "compilerOptions": { "module": "commonjs", }
所以,在ts文件里,也可以直接按node的commonjs的写法:
3.2自己写的代码库
又分好几种情况
服务器端用:
1ts写,供ts调用
其实反而和es6差不多,直接结尾export {}即可,最简单。
还可能将来复用到ng等等别的地方。
2 js写,commonjs方式,供ts调用
3 es6写的js,供ts调用
这样的目的,是试图这个js库准备兼容浏览器和服务端,两边都使用。
如果js里是es6的写法 export {} 直接执行测试,会报错,SyntaxError: Unexpected token export
怎么都搞不定,还是看ts官网 Migrating from JavaScript
在tsconfig.json里加入
直接搞定。
原因:
如果没有这个选项,那么tsc遇到js时不处理,然后node用commonjs模块机制处理,那么目前就还不认识export关键字。所以报错了;
如果打开这个选项,tsc会去处理js文件,ts是认识exports关键字的,在别处 import from 就没事了。
——坑点:TM这个选项,还有很多别的选项,可能没列在默认的tsconfig.json里啊啊啊(tsconfig.json也许来自其他地方copy过来的,2333)。那么tsc是个超多选项的cli,那么多默认参数,新手不可能每个都知道。如果tsconfig.json写漏了就麻烦了。
4 noImplicitAny , true or false?
如果true,函数的形参必须带类型,如果叫不出class名的js对象,那就得any,比如(d:any)=>{}如果false,函数的样子更像js (d)=>{}
既可以是正规军的“有状态的部队”写法:namespace下辖class,class下辖method也可以是扁平化,“无状态的分队”写法: module辖var,function
保留不加类型注解的权利,也要获得加类型注解的权利。
1 这个选项设置为false。自定义的ts类加注解(写node毕竟不是用ng写web component,没有那么多class),string number这样的基本类型加注解。2 其他的地方不加类型注解,特别是d3 数据绑定时等等常用的(d)=>{}写法,继续保留不加注解的写法。