用TypeScript編寫釋出函式庫

螞蟻金服資料體驗技術發表於2017-11-09

作者簡介 zqlu 螞蟻金服·資料體驗技術團隊

為什麼使用TypeScript編寫函式庫

TypeScript作為一種有型別定義的JavaScript超集語言,用來寫函式庫除了給自己開發者自己帶來如開發效率提升、靜態檢查等好處外,對庫的使用方也能帶來一下好處:

  • 對於直接使用JavaScript的使用者,通過TypeScript的編譯過程,可以生成直接使用的JavaScript程式碼,如ES5版本的JavaScript程式碼,對使用者的使用沒有影響
  • 對於使用TypeScript的開發者,通過TypeScript編譯生成的定義檔案,能極大提升使用者的使用體驗

函式庫的編譯控制

程式碼庫在釋出之後,使用者可能期望能以各種方式來使用庫,如直接在瀏覽器中載入使用、通過NodeJs的CommonJS模組方式來引用程式碼庫、或者直接通過ES6的module方式來引用。

在使用TypeScript編寫程式碼庫後,開發者可以不用關心程式碼庫使用者的飲用方式,而直接使用TypeScript的模組機制來模組化編寫程式碼庫;而是在通過TypeScript的編譯過程來生成

下面分別介紹以上幾種不同使用情景下的編譯過程。

CommonJS模組化程式碼的生成

目前前端開發庫絕大部分都會發布到npm上,npm作為NodeJs的包管理器,提供CommonJs的模組化程式碼是非常有必要的。

通過tsconfig.json來配置CommonJS模組程式碼的生成:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist/cmjs",
    "rootDir": "./src",
    "declaration": true,
    "sourceMap": true,
    "lib": ["dom", "es6"]
  }
}
複製程式碼

通過以上配置, "module": "commonjs" 來申明編譯生成目的碼模組為commonjs,生成目的碼目錄為:"outDir": "dist/cmjs"

同時在package.json中,通過main欄位來申明CommonJS的入口檔案:

{
  	"name": "myLib",
  	"version": "0.1.0",
    "main": "dist/cmjs/index.js",
}
複製程式碼

ES6模組程式碼的生成

隨著ES6標準的流行,以及各種打包工具對ES6模組的原生支援,如webpack的resolve.mainFields配置,提供ES6模組程式碼能夠讓使用者享受ES6模組的一些特性。

同CommonJS一樣,也可以通過配置tsconfig.json的方式來生成ES6模組程式碼,但一般在tsconfig.json中使用commonjs作為預設配置,所以可以在package.json中通過新增script來通過TypeScript編譯器命令列引數來編譯生成ES6模組程式碼:

{
    "name": "myLib",
  	"script": {
        "build:cmjs": "tsc -P tsconfig.json",
      	"build:es6": "tsc -P tsconfig.json --module ES6 --outDir dist/es6",
      	"build": "npm run build:cmjs; npm run build:es6"
    }
}
複製程式碼

其中 build:cmsj 編譯生成CommonJS模組目的碼,build:es6編譯生成ES6模組目的碼。對於ES6模組的程式碼,通過在package.json中的module欄位來申明ES6模組程式碼的入口檔案,以便能夠識別ES6模組的模組載入器使用:

{
  	"name": "myLib",
  	"version": "0.1.0",
    "main": "dist/cmjs/index.js",
 	"module": "dist/es6/index.js",
}
複製程式碼

能夠直接給瀏覽器使用的程式碼生成

生成能夠直接給瀏覽器使用的程式碼,能夠方便使用者,不需要使用包管理器,直接在html檔案中引用。如React,可以直接在HTML檔案中引入dist/react.js單獨檔案。對此,需要對模組化分佈的程式碼按依賴合併大包,所以使用打包工具如webpack完全可以做到,這裡不仔細介紹。

另外,還可以可以藉助Browserify工具來將上述編譯生成的CommonJS模組化程式碼整體打包成可供瀏覽器直接使用的程式碼。同樣,通過簡單的新增package.json的script來完成:

{
    "name": "myLib",
  	"script": {
        "build:cmjs": "tsc -P tsconfig.json",
      	"build:es6": "tsc -P tsconfig.json --module ES6 --outDir dist/es6",
      	"build:web": "browserify dist/cmjs/index.js --standalone myLib -o dist/web/bundle.js",
      	"build": "npm run build:cmjs; npm run build:es6"
    }
}
複製程式碼

版本與釋出

語義化版本

語義化版本使用如:主版本號.次版本號.修訂號 的版本格式,有詳細嚴格的定義文件。遵循語義化版本號規則有利於使用者理解程式碼庫的升級修改,共同遵循語義化版本號能使開發者和使用者共同獲益。

此外,文件中還提到了一些常見的問題,如:

  • 在函式庫開發階段,如果控制版本號?推薦是從0.1.0版本開始
  • 如何判斷髮布1.0.0的時機?軟體被應用在正式環境;有固定的API被使用者依賴;存在向下相容問題的時候
  • 對於公共API,即使是最小但向下不相容的改變都需要產生新的主版本號,豈不是很快就到了如42.0.0版?這是開發的責任感和前瞻性的問題,為什麼有這麼多不相容更改:)

釋出版本

在TypeScript編寫函式庫後,需要更新版本時候,推薦使用npm version命令來更新版本號,如:

  • 更新修訂號:npm version patch

  • 更新此版本號:npm version minor

  • 更新主版本號:npm version major

執行上述命令,會增加相應的版本號儲存到package.json的version欄位中。在使用git做原始碼版本控制的時候,還可以新增-m引數來自動成來提供一條版本更新commit記錄和tag記錄,如執行npm version patch -m "update version %s"除了更新package.json中的version欄位外,還會自動生成一條commit記錄,commit message中的%m 會被替換成新生成的版本號,此外還有自定生成tag記錄。

對Typescript感興趣的同學可以關注專欄或者傳送簡歷至'lingdao.lzq####alibaba-inc.com'.replace('####', '@'),歡迎有志之士加入~

原文地址:github.com/ProtoTeam/b…

相關文章