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,哈哈哈
相關文章
相關標籤/搜索