TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source. ———— TypeScript 官網
據 rollbar 統計,在前端項目中 10 大錯誤類型如下圖所示:
其中有 7 個是類型錯誤(TypeError):
Cannot read property xxx on undefined
undefined is not an object
undefined
null is not an object
undefined is not a function
a.b.c()
Object doesnt support property
Cannot read property length
length
Cannot set property of undefined
除了 7 個 TypeError,還有一個 ReferenceError:
xxx is not defined
還有一個 RangeError:
嘿嘿,看著這些錯誤眼不眼熟?
由於 JavaScript 是一門很靈活的語言,所以以上這些錯誤往往要在代碼運行時才能發現。
在使用 JavaScript 時,編輯器的智能提示往往很有限,比如提示你最近輸入的變數。
但是基於 TypeScript,由於知道當前變數是什麼類型,所以編輯器能經過類型推導後為你提示這個變數的所有屬性,以及對於函數的參數進行提示和校驗。
此外,對於一般的 JavaScript 項目也可以自己編寫 .d.ts 聲明文件,來獲取類型推導能力。
.d.ts
至於其他的優點在這裡就不展開了...
綜上,在項目中使用 TypeScript 能讓你極大地提高工作效率,並減少大量的類型錯誤。
由於目前業務項目中的框架用的是 Vue.js,眾所周知 2.x 版本對於 TypeScript 支持的不是很好,所以就打算先搞個工具函數庫項目試試水。
略,這個各種資料很多,這裡就不贅述了...
src/index.ts
export * from ...
test/
docs/
注意:package.json 中的 sideEffects 欄位要寫成 false,這樣可以方便業務代碼打包時 tree-shaking。
package.json
sideEffects
false
tree-shaking
之前對於 TypeScript 一直在觀望的原因之一就是相關工具鏈的搭配還不是很成熟。不過現在倒是基本明晰了:
babel
TypeScript 和 babel 都可以將你的 ES6+ 代碼轉成 ES5。
但在 Babel v7 之前將兩個獨立的編譯器(TypeScript 和 Babel)鏈接在一起並非易事。編譯流程變為:TS > TS Compiler > JS > Babel > JS (again)。
TS > TS Compiler > JS > Babel > JS (again)
現在只要安裝 @babel/preset-typescript 這個包就能讓你完美結合 babel 和 TypeScript。
eslint
再也不用糾結到底用 tslint 還是 eslint 了,TypeScript 官方已經欽定了 eslint(Migrate the repo to ESLint #30553)。
jest
嘿嘿,Facebook 的 jest 和 yarn(Yarns Future - v2 and beyond #6953) 都拋棄自家的 Flow 轉投 TypeScript 的懷抱了
rollup
雖然 rollup 自己用的是 rollup-plugin-typescript,不過項目中還是選了 rollup-plugin-typescript2。
rollup-plugin-typescript
rollup-plugin-typescript2
tsconfig.json
.js
.ts
TypeScript 官方有一套基於 jsdoc 的文檔標準 tsdoc。
export class Statistics { /** * Returns the average of two numbers. * * @remarks * This method is part of the {@link core-library#Statistics | Statistics subsystem}. * * @param x - The first input number * @param y - The second input number * @returns The arithmetic mean of `x` and `y` * * @beta */ public static getAverage(x: number, y: number): number { return (x + y) / 2.0; } }
於是順藤摸瓜找到 typedoc 這個自動文檔網站生成器。但這玩意兒的常規操作就是讀取源代碼,然後 duang 地一下,生成一堆頁面。
雖然這樣解決了文檔生成,但是沒法進行開發時實時預覽文檔。
0.失敗嘗試:結合 vuepress
由於 typedoc 能導出 md 文件,所以嘗試過將其結合 vuepress。不過由於 typedoc 在生成時會先清空目標目錄下所有文件,折騰起來太麻煩(比如做個插件)。
1.下策:手動觸發文檔生成
沒啥好說的,適用於有毅力的同學。
2.中策:監聽源文件變化,自動觸發文檔生成
雖然能自動生成文檔頁面了,不過預覽時沒法自動刷新頁面。
3.上策:藉助 webpack、gulp、grunt 自動生成文檔並刷新頁面(正好有這三者的 typedoc 插件)
說到開發時自動刷新頁面,第一個自然想到 browser-sync。
最後這裡貼一下 gulpfile.js 的代碼,節省一下也有相關需求同學的時間吧。
gulpfile.js
const gulp = require(gulp) const typedoc = require(gulp-typedoc) const browserSync = require(browser-sync).create()
const runTypeDoc = () => gulp .src([src]) .pipe(typedoc({ out: ./docs, // 這個文件裏都是 export * from ... 就沒必要導出文檔了 exclude: src/index.ts, tsconfig: tsconfig.json, }))
const reload = (done) => { browserSync.reload() done() }
const runBrowserSync = (done) => { browserSync.init({ server: { baseDir: ./docs, }, }) done() }
const watch = () => gulp.watch( [README.md, src/*.ts], gulp.series(runTypeDoc, reload) )
gulp.task(default, gulp.series(runTypeDoc, runBrowserSync, watch))
以上 to be continued...
推薦閱讀: