ts-demo-npm-cjs.gitignore.npmignorepackage.jsondependencies vs. devDependenciespackage.jsontsconfig.jsonindex.tsindex_test.tsDieses Kapitel beschreibt, wie man mit TypeScript Pakete für den Paketmanager npm erstellt, die auf dem CommonJS-Modulformat basieren.
GitHub-Repository:
ts-demo-npm-cjs
In diesem Kapitel untersuchen wir das Repository ts-demo-npm-cjs, das von GitHub heruntergeladen werden kann. (Ich habe es bewusst nicht als Paket bei npm veröffentlicht.)
Sie sollten ungefähr vertraut sein mit
CommonJS-Modulen – einem Modulformat, das aus dem serverseitigen JavaScript stammt und dafür entwickelt wurde. Es wurde von der serverseitigen JavaScript-Plattform Node.js populär gemacht. CommonJS-Module gingen den eingebauten ECMAScript-Modulen von JavaScript voraus und werden immer noch häufig verwendet und von Tools (IDEs, Build-Tools usw.) sehr gut unterstützt.
TypeScript-Modulen – deren Syntax auf ECMAScript-Modulen basiert. Sie werden jedoch oft zu CommonJS-Modulen kompiliert.
npm-Paketen – Verzeichnisse mit Dateien, die über den npm-Paketmanager installiert werden. Sie können CommonJS-Module, ECMAScript-Module und verschiedene andere Dateien enthalten.
In diesem Kapitel verwenden wir das, was TypeScript derzeit am besten unterstützt
.js kompiliert.Insbesondere unter Node.js unterstützt TypeScript derzeit nicht wirklich ECMAScript-Module und Dateiendungen außer .js.
ts-demo-npm-cjsSo ist das Repository ts-demo-npm-cjs strukturiert
ts-demo-npm-cjs/
.gitignore
.npmignore
dist/ (created on demand)
package.json
ts/
src/
index.ts
test/
index_test.ts
tsconfig.json
Neben der package.json für das Paket enthält das Repository
ts/src/index.ts: der eigentliche Code des Paketsts/test/index_test.ts: ein Test für index.tstsconfig.json: Konfigurationsdaten für den TypeScript-Compilerpackage.json enthält Skripte zum Kompilieren
ts/ (TypeScript-Code)dist/ (CommonJS-Module; das Verzeichnis existiert im Repository noch nicht)Hier werden die Kompilierungsergebnisse für die beiden TypeScript-Dateien abgelegt
ts/src/index.ts --> dist/src/index.js
ts/test/index_test.ts --> dist/test/index_test.js
.gitignoreDiese Datei listet die Verzeichnisse auf, die wir nicht in Git einchecken wollen
node_modules/
dist/
Erläuterungen
node_modules/ wird über npm install eingerichtet.dist/ werden vom TypeScript-Compiler erstellt (mehr dazu später)..npmignoreWenn es darum geht, welche Dateien zum npm-Registry hochgeladen werden sollen und welche nicht, haben wir andere Anforderungen als bei Git. Daher benötigen wir zusätzlich zu .gitignore auch die Datei .npmignore
ts/
Die beiden Unterschiede sind
dist/).ts/).Beachten Sie, dass npm das Verzeichnis node_modules/ standardmäßig ignoriert.
package.jsonpackage.json sieht so aus
{
···
"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": "···"
}
}Werfen wir einen Blick auf die Eigenschaften
type: Der Wert "commonjs" bedeutet, dass .js-Dateien als CommonJS-Module interpretiert werden.main: Wenn es einen sogenannten bare import gibt, der nur den Namen des aktuellen Pakets erwähnt, dann ist dies das Modul, das importiert wird.types verweist auf eine Deklarationsdatei mit allen Typdefinitionen für das aktuelle Paket.Die nächsten beiden Unterabschnitte behandeln die restlichen Eigenschaften.
Die Eigenschaft scripts definiert verschiedene Befehle, die über npm run aufgerufen werden können. Zum Beispiel wird das Skript clean über npm run clean aufgerufen. Die vorherige package.json enthält die folgenden Skripte
clean verwendet das plattformübergreifende Paket shx, um die Kompilierungsergebnisse über seine Implementierung des Unix-Shell-Befehls rm zu löschen. shx unterstützt eine Vielzahl von Shell-Befehlen mit dem Vorteil, dass für jeden Befehl, den wir verwenden möchten, kein separates Paket benötigt wird.
build und watch verwenden den TypeScript-Compiler tsc, um die TypeScript-Dateien gemäß tsconfig.json zu kompilieren. tsc muss global oder lokal (innerhalb des aktuellen Pakets) installiert sein, normalerweise über das npm-Paket typescript.
test und testall verwenden das Unit-Test-Framework Mocha, um einen oder alle Tests auszuführen.
prepack: Dieses Skript wird vor dem Packen eines Tarballs ausgeführt (aufgrund von npm pack, npm publish oder einer Installation von git).
Beachten Sie, dass wir bei der Verwendung einer IDE die Skripte build und watch nicht benötigen, da wir die IDE die Artefakte erstellen lassen können. Sie werden jedoch für das Skript prepack benötigt.
dependencies vs. devDependenciesdependencies sollten nur die Pakete enthalten, die beim Importieren eines Pakets benötigt werden. Dies schließt Pakete aus, die zum Ausführen von Tests usw. verwendet werden.
Pakete, deren Namen mit @types/ beginnen, stellen TypeScript-Typdefinitionen für Pakete bereit, die keine eigenen haben. Ohne erstere können wir letztere nicht verwenden. Sind dies normale Abhängigkeiten oder Dev-Abhängigkeiten? Das hängt davon ab
Wenn die Typdefinitionen unseres Pakets auf Typdefinitionen in einem anderen Paket verweisen, ist dieses Paket eine normale Abhängigkeit.
Andernfalls wird das Paket nur während der Entwicklungszeit benötigt und ist eine Dev-Abhängigkeit.
package.jsonpackage.json erklärt verschiedene Eigenschaften dieser Datei.scripts erklärt die package.json-Eigenschaft scripts.tsconfig.json{
"compilerOptions": {
"rootDir": "ts",
"outDir": "dist",
"target": "es2019",
"lib": [
"es2019"
],
"module": "commonjs",
"esModuleInterop": true,
"strict": true,
"declaration": true,
"sourceMap": true
}
}rootDir: Wo befinden sich unsere TypeScript-Dateien?
outDir: Wohin sollen die Kompilierungsergebnisse gelegt werden?
target: Welche ECMAScript-Version ist das Ziel? Wenn der TypeScript-Code eine Funktion verwendet, die von der Zielversion nicht unterstützt wird, wird sie in äquivalenten Code kompiliert, der nur unterstützte Funktionen verwendet.
lib: Welche Plattformfunktionen sollte TypeScript kennen? Möglichkeiten sind die ECMAScript-Standardbibliothek und das DOM von Browsern. Die Node.js-API wird anders unterstützt, über das Paket @types/node.
module: Gibt das Format der Kompilierungsausgabe an.
Die übrigen Optionen werden von der offiziellen Dokumentation für tsconfig.json erklärt.
index.tsDiese Datei liefert die eigentliche Funktionalität des Pakets
import endsWith from 'lodash/endsWith';
export function removeSuffix(str: string, suffix: string) {
if (!endsWith(str, suffix)) {
throw new Error(JSON.stringify(suffix)} + ' is not a suffix of ' +
JSON.stringify(str));
}
return str.slice(0, -suffix.length);
}Sie verwendet die Funktion endsWith() der Bibliothek Lodash. Deshalb ist Lodash eine normale Abhängigkeit – sie wird zur Laufzeit benötigt.
index_test.tsDiese Datei enthält einen Unit-Test für index.ts
import { strict as assert } from 'assert';
import { removeSuffix } from '../src/index';
test('removeSuffix()', () => {
assert.equal(
removeSuffix('myfile.txt', '.txt'),
'myfile');
assert.throws(() => removeSuffix('myfile.txt', 'abc'));
});Wir können den Test wie folgt ausführen
npm t dist/test/index_test.js
t ist eine Abkürzung für den npm-Befehl test.test ist eine Abkürzung für run test (der das Skript test aus package.json ausführt).Wie Sie sehen, führen wir die kompilierte Version des Tests (im Verzeichnis dist/) aus, nicht den TypeScript-Code.
Weitere Informationen zum Unit-Test-Framework Mocha finden Sie auf seiner Homepage.