node+ts的心得与坑

首先先明确,用node+ts的目的,为何不ng+ts。这一点后面还会反复提醒本身 node毕竟不是ng。javascript

用node的理由:html

处理js,在后端操纵dom,读写类html格式的东西,比直接用py的后端更舒服。java

着眼点仍是后端数据处理,做为相似单机版数据库的后台进程db_master(RESTful API等于 数据库的CRUD)。node

不须要写界面,不须要web component这些。因此用ts,不意味着,处处都是class。仍然是data居多,function居多。程序员

用ts的理由:es6

主要理由:给了增长类型注解的选择权,export方式也更贴近es6标准。web

不太成立的理由:本身毕竟写过了点ng。ts用着还能够,其实es6自己,通过2015 2016 2017,也很不错了。typescript

 

用node+ts稍微写点东西,就发现数据库

1 各类库必须本身知道选择,安装。npm

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开发者角度看遇到的很别扭的坑。

 

1 @types

为了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'
describe('Hello function', () => {
  it('should return hello world', () => {
  const result = helloword();
   expect(result).to.equal('Hello World!');
});
})

而后是在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的写法:

var d3 = require('d3');
这样用。
没必要须import from,  node毕竟不是ng。

3.2本身写的代码库

 又分好几种状况

服务器端用:

1ts写,供ts调用

其实反而和es6差很少,直接结尾export {}便可,最简单。

还可能未来复用到ng等等别的地方。

2 js写,commonjs方式,供ts调用

直接node的commonjs方式 文件结尾 module.exports = {XXX,}
若是只准备在node端用的代码,这样也够了,但不如1

3 es6写的js,供ts调用

 这样的目的,是试图这个js库准备兼容浏览器和服务端,两边都使用。

若是js里是es6的写法 export {}   直接执行测试,会报错,SyntaxError: Unexpected token export

怎么都搞不定,仍是看ts官网 Migrating from JavaScript

在tsconfig.json里加入

"compilerOptions": {
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true,
"target": "es6",
"noImplicitAny": false,
"allowJs": true,
...
}

直接搞定。

缘由:

若是没有这个选项,那么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?

tsconfig.json里的noImplicitAny能够控制:
若是true,函数的形参必须带类型,若是叫不出class名的js对象,那就得any,好比(d:any)=>{}
若是false,函数的样子更像js  (d)=>{}
 
到底用不用强制写class?
 
若是false,并且确实什么类型注解都不写,那么用ts的意思其实不大了,直接写原生的es6就能够了,推荐阮一峰老师的《ES6标准入门 第3版》
可是true的话,又处处都是any尤为是(d:any)=>{} ,确实很丑,很没有必要,ts的类型声明只是注解,毕竟仍是要转成js执行的。ts也毕竟不是java,我也不是java程序员。
并且,如今写了这么久的代码,本身的感受不是“一切都是类”,“一切都是函数”,“一切都是文件”,而是“该是class的才是class,该是function的,就是function”。
 
一个工程就好像一支军队,成军之法:
既能够是正规军的“有状态的部队”写法:namespace下辖class,class下辖method
也能够是扁平化,“无状态的分队”写法: module辖var,function
 
个人ts,不能给搞成彻底没有类型的史前js;也不能矫枉过正,强制搞成了java,搞得一切必须弄成class,层层的封装。
 
因此,最佳选择是得到更多的选择权:
保留不加类型注解的权利,也要得到加类型注解的权利。
 所以
1 这个选项设置为false。自定义的ts类加注解(写node毕竟不是用ng写web component,没有那么多class),string number这样的基本类型加注解。
2 其余的地方不加类型注解,特别是d3 数据绑定时等等经常使用的(d)=>{}写法,继续保留不加注解的写法。
 这样用起来,更像py,哈哈哈
相关文章
相关标签/搜索