ts-demo-npm-cjs
.gitignore
.npmignore
package.json
dependencies
與 devDependencies
package.json
的更多資訊tsconfig.json
index.ts
index_test.ts
本章節說明如何使用 TypeScript 建立基於 CommonJS 模組格式的套件管理員 npm 套件。
GitHub 儲存庫:
ts-demo-npm-cjs
在本章節中,我們將探討 儲存庫 ts-demo-npm-cjs
,可以在 GitHub 上下載。(我故意沒有將其作為套件發布到 npm。)
您應該大致熟悉
CommonJS 模組 – 一種起源於伺服器端 JavaScript 並為其設計的模組格式。它由伺服器端 JavaScript 平台 Node.js 推廣。CommonJS 模組早於 JavaScript 內建的 ECMAScript 模組,並且仍然被廣泛使用,並受到工具(IDE、內建工具等)的良好支援。
TypeScript 的模組 – 其語法基於 ECMAScript 模組。但是,它們通常會編譯為 CommonJS 模組。
npm 套件 – 透過 npm 套件管理員安裝的包含檔案的目錄。它們可以包含 CommonJS 模組、ECMAScript 模組和各種其他檔案。
在本章節中,我們使用 TypeScript 目前最支援的
.js
。特別是在 Node.js 上,TypeScript 目前並不真正支援 ECMAScript 模組和 .js
以外的檔案名稱副檔名。
ts-demo-npm-cjs
儲存庫 ts-demo-npm-cjs
的結構如下
ts-demo-npm-cjs/
.gitignore
.npmignore
dist/ (created on demand)
package.json
ts/
src/
index.ts
test/
index_test.ts
tsconfig.json
除了套件的 package.json
外,儲存庫包含
ts/src/index.ts
:套件的實際程式碼ts/test/index_test.ts
:index.ts
的測試tsconfig.json
:TypeScript 編譯器的設定資料package.json
包含編譯的腳本
ts/
(TypeScript 程式碼)dist/
(CommonJS 模組;此目錄目前尚未存在於儲存庫中)這是兩個 TypeScript 檔案編譯結果的放置位置
ts/src/index.ts --> dist/src/index.js
ts/test/index_test.ts --> dist/test/index_test.js
.gitignore
此檔案列出我們不想檢查到 git 的目錄
node_modules/
dist/
說明
node_modules/
是透過 npm install
設定的。dist/
中的檔案是由 TypeScript 編譯器建立的(稍後會詳細說明)。.npmignore
在哪些檔案應該上傳到 npm 註冊表,哪些不應該上傳的部分,我們的需求與 git 不同。因此,除了 .gitignore
之外,我們還需要檔案 .npmignore
ts/
兩個不同點是
dist/
)。ts/
)。請注意,npm 預設會忽略目錄 node_modules/
。
package.json
package.json
如下所示
{
···
"type": "commonjs",
"main": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"scripts": {
"clean": "shx rm -rf dist/*",
"build": "tsc",
"watch": "tsc --watch",
"test": "mocha --ui qunit",
"testall": "mocha --ui qunit dist/test",
"prepack": "npm run clean && npm run build"
},
"// devDependencies": {
"@types/node": "Needed for unit test assertions (assert.equal() etc.)",
"shx": "Needed for development-time package.json scripts"
},
"devDependencies": {
"@types/lodash": "···",
"@types/mocha": "···",
"@types/node": "···",
"mocha": "···",
"shx": "···"
},
"dependencies": {
"lodash": "···"
}
}
我們來看一下屬性
type
:值 "commonjs"
表示 .js
檔案會被解釋為 CommonJS 模組。main
:如果有一個僅提到目前套件名稱的所謂裸入,則這是會被匯入的模組。types
指向一個宣告檔,其中包含目前套件的所有類型定義。接下來的兩個小節會說明其餘的屬性。
屬性 scripts
定義各種可透過 npm run
呼叫的命令。例如,腳本 clean
是透過 npm run clean
呼叫的。先前的 package.json
包含下列腳本
clean
使用 跨平台套件 shx
透過實作 Unix shell 指令 rm
來刪除編譯結果。shx
支援各種 shell 指令,而且不需要為我們可能想要使用的每個指令安裝獨立的套件。
build
和 watch
使用 TypeScript 編譯器 tsc
根據 tsconfig.json
編譯 TypeScript 檔案。tsc
必須在全域或本機(在目前套件中)安裝,通常透過 npm 套件 typescript
安裝。
test
和 testall
使用 單元測試架構 Mocha 來執行一個測試或所有測試。
prepack
:此腳本會在打包 tarball 之前執行(因為 npm pack
、npm publish
或從 git 安裝)。
請注意,當我們使用 IDE 時,不需要腳本 build
和 watch
,因為我們可以讓 IDE 建立成品。但是 prepack
腳本需要這些腳本。
dependencies
與 devDependencies
dependencies
應該只包含在匯入套件時需要的套件。這會排除用於執行測試等用途的套件。
名稱以 @types/
開頭的套件會提供沒有任何類型定義的套件的 TypeScript 類型定義。沒有前者,我們就無法使用後者。這些是一般的相依性還是開發相依性?這取決於
如果我們套件的類型定義會參照另一個套件中的類型定義,那個套件就是一般的相依性。
否則,套件只會在開發期間需要,而且是開發相依性。
package.json
的更多資訊package.json
的 npm 文件 說明該檔案的各種屬性。scripts
的 npm 文件 說明 package.json
屬性 scripts
。tsconfig.json
{
"compilerOptions": {
"rootDir": "ts",
"outDir": "dist",
"target": "es2019",
"lib": [
"es2019"
],
"module": "commonjs",
"esModuleInterop": true,
"strict": true,
"declaration": true,
"sourceMap": true
}
}
rootDir
:我們的 TypeScript 檔案位於何處?
outDir
:編譯結果應該放在何處?
target
:目標 ECMAScript 版本為何?如果 TypeScript 程式碼使用目標版本不支援的功能,則會編譯為只使用受支援功能的等效程式碼。
lib
:TypeScript 應該注意哪些平台功能?可能性包括 ECMAScript 標準函式庫和瀏覽器的 DOM。Node.js API 以不同的方式透過套件 @types/node
提供支援。
module
:指定編譯輸出的格式。
其餘選項由 tsconfig.json
的官方文件 說明。
index.ts
此檔案提供套件的實際功能
import endsWith from 'lodash/endsWith';
function removeSuffix(str: string, suffix: string) {
export if (!endsWith(str, suffix)) {
new Error(JSON.stringify(suffix)} + ' is not a suffix of ' +
throw JSON.stringify(str));
}.slice(0, -suffix.length);
return str }
它使用 函式庫 Lodash 的函式 endsWith()
。這就是 Lodash 是正常相依性的原因,因為它在執行階段需要。
index_test.ts
此檔案包含 index.ts
的單元測試
import { strict as assert } from 'assert';
import { removeSuffix } from '../src/index';
test('removeSuffix()', () => {
.equal(
assertremoveSuffix('myfile.txt', '.txt'),
'myfile');
.throws(() => removeSuffix('myfile.txt', 'abc'));
assert; })
我們可以像這樣執行測試
npm t dist/test/index_test.js
t
是 npm 指令 test
的縮寫。test
是 run test
的縮寫(它執行 package.json
中的指令碼 test
)。如你所見,我們執行的是測試的已編譯版本(在目錄 dist/
中),而不是 TypeScript 程式碼。
有關單元測試框架 Mocha 的更多資訊,請參閱 其首頁。