Запис модулів NPM в Typescript


103

Я працюю над своїм першим модулем NPM. Раніше я коротко працював з машинописом, і великою проблемою було те, що для багатьох модулів не було доступних файлів визначення. Тому я подумав, що було б гарною ідеєю написати свій модуль в машинописі.

Однак я не можу знайти будь-яку інформацію про найкращий спосіб зробити це. Я знайшов відповідне запитання " Чи можу я написати пакет npm у coffeescript? ", Де люди пропонують публікувати лише файли javascript. Але на відміну від файлів coffeescript, файли машинописів можуть бути корисними, якщо вони використовуються в програмі typecript.

Чи слід включати файли Typescript при публікації модуля NPM або я повинен публікувати лише файли javascript та надавати згенеровані файли .d.ts на DefinitelyTyped?


2
Корисні примітки: Я написав проект, copee , разом із публікацією в блозі, щоб провести вас через налаштування проекту TS для випромінювання визначень типів разом із цілями CJS та ESM перед публікацією в npm. Це дозволить максимально використовувати, коли node.js та веб-переглядачі переходять уперед.
стайф

Відповіді:


84

Ось зразок модуля Node, написаний у TypeScript: https://github.com/basarat/ts-npm-module

Ось зразок проекту TypeScript, який використовує цей зразок модуля https://github.com/basarat/ts-npm-module-consume

В основному вам потрібно:

  • компілювати з commonjsіdeclaration:true
  • створити .d.tsфайл

І потім

  • Нехай ваша ідея читає створене .d.ts.

Atom-TypeScript просто забезпечує хороший робочий процес навколо цього: https://github.com/TypeStrong/atom-typescript#packagejson-support


Якірне посилання Atom-TypeScript потрібно оновити (прив’язка вже не дійсна).
Фідан Хакай

@basarat, у ts-npm-модулі ви використовуєте "version": "1.5.0-alpha". Я припускаю, що це версія Typescript, яку ви перекладаєте. Чи не важливо це залишити? (це не робиться автоматично плагіном Atom). Якщо використовується версія, чи вимагатиме це від інших користувачів точну версію для транспіляції (або лише новішої)? (Або , може бути , це версія tsconfig.json?)
Justin

Чи є у вас випадки використання модулів залежно від інших бібліотек? Щоб уникнути проблеми з дублюванням визначення, вам потрібно налаштувати tsconfig.json, але це здається занадто ручним на мою думку.
Серхіо Міхельс

1
Ви б все-таки виступали за такий підхід у другому кварталі 2016 року?
SuperUberDuper

7
Це було приємно як - tsmean.com/articles/how-to-write-a-typescript-library
chrismarx

78

Для TypeScript 3.x або TypeScript 2.x наступні кроки описують, що вам потрібно зробити, щоб створити бібліотеку (npm-пакет) з TypeScript:

  • Створіть проект так, як зазвичай (з тестами та всім)
  • Додати declaration: trueвtsconfig.json створення типізацій.
  • Експортуйте API через index.ts
  • У полі package.jsonвкажіть на створені вами типізації. Наприклад, якщо ваш outDirє dist, то додайте"types": "dist/index.d.ts" у свій пакет json.
  • У полі package.jsonвкажіть ваш основний файл входу. Наприклад, якщо ваш файл outDirє distі основний файл index.js, тоді додайте"main": "dist/index.js" до вашого package.json.
  • Створіть .npmignore ігнорувати непотрібні файли (наприклад, джерело).
  • Опублікувати в npm за допомогою npm publish. Використовуйте технічні характеристики semver для оновлень (виправлення виправлень / помилок npm version patch, беззбиткові доповнення npm version minor, порушення api-змін npm version major)

Оскільки у мене з’явився час просіяти всі застарілі ресурси на цю тему в Інтернеті (як, наприклад, на цій сторінці ...), я вирішив перетворити його в бібліотеку "як писати-писати-пишети" з сучасний робочий мінімальний приклад.


Чи доведеться мені перевірити js у контролі джерела? Або npm зберігає власну версію коду?
Olian04

1
@ Olian04 Ви кажете створити .npmignoreфайл, щоб повідомити npm, які файли ігнорувати під час публікації ( .tsфайли) та a, .gitignoreщоб сказати git, які файли ігнорувати ( dist/)
Purag,

@ Olian04 ні, вам не потрібно (і IMO не повинен) здійснювати створення генерованих файлів JS. Вони не є частиною джерела проекту.
Джош М.

59

Це більш свіжа відповідь за допомогою TypeScript 1.8.10:

Моя структура проекту:

|
|--- src
|--- test
|--- dist     <= My gulp file compiles and places the js, sourcemaps and .d.ts files here
|      |--- src
|      |--- test
|--- typings
.gitignore
.npmignore
gulpfile.js
package.json
README.md
tsconfig.json
tslint.json
typings.json

Я додав наступне, .npmignoreщоб уникнути включення сторонніх файлів і зберегти мінімальний мінімум, щоб пакет імпортувався та працював:

node_modules/
*.log
*.tgz

src/
test/
gulpfile.js
tsconfig.json
tslint.json
typings.json
typings
dist/test

Моє .gitignore:

typings

# ignore .js.map files
*.js.map
*.js
dist

Моє package.json:

"main": "dist/src/index.js",
"typings":  "dist/src/index.d.ts",

Зараз я бігаю: npm pack

Отриманий файл (при розпакуванні) має таку структуру:

|
|--- dist
|       |--- src
|              |
|              index.js
|              index.js.map
|              index.d.ts
|
package.json
README.md

Тепер я переходжу до проекту, де я хочу використовувати це як бібліотеку та ввести: npm install ./project-1.0.0.tgz

Він успішно встановлюється.

Тепер я створюю файл index.tsу своєму проекті, де я щойно встановив npm import Project = require("project");

Введення тексту Project.дає мені параметр Intellisense, який був пунктом всієї цієї вправи.

Сподіваємось, це допомагає комусь іншому у використанні своїх проектів TypeScript npm як внутрішніх бібліотек у своїх великих проектах.

PS: Я вважаю , що такий підхід складання проектів по НПМ модулів , які можуть бути використані в інших проектах , нагадує .dllв .NETсвіті. Я цілком можу уявити, що проекти організовуються за рішенням у коді VS, де кожен проект створює пакет npm, який потім може бути використаний в іншому проекті рішення як залежність.

Оскільки мені знадобилося досить багато часу, щоб я це зрозумів, я розмістив це на випадок, якщо хтось застряг тут.

Я також опублікував її для закритої помилки за адресою: https://github.com/npm/npm/isissue/11546


Цей приклад завантажено в Github: vchatterji / tsc-seed


Ви можете завантажити приклад на github? Це б дуже допомогло! :)
Хан Че

3
Приклад завантажено в Github: github.com/vchatterji/tsc-seed
Varun Chatterji

Як він також може бути використаний у проектах, що не друкують машинопис?
SuperUberDuper

5

Ви повинні публікувати оригінальні джерела машинопису замість визначення типу. В package.jsonНехай точка властивості «типів» в * .ts файл.

*.d.ts добре коментувати існуючі JS-файли, але, як споживач, я б швидше читав код машинопису, ніж перемикався між визначеннями типів та зрівнюваним JS-кодом.


1
Здається, компілятор TypeScript поки що не підходить для цього. Дивіться цю проблему github.com/Microsoft/TypeScript/isissue/14479
Sven Efftinge

2
наразі в тому числі *.d.ts- це рекомендований спосіб зробити це, хоча я погоджуюсь з вами переваги включати *.tsфайли, typecriptlang.org/docs/handbook/declaration-files/…
Тім,

5

Я в основному дотримуюся пропозиції Варуна Чаттерджі

Але я хотів би показати повний приклад з тестуванням одиниць та охопленням коду, а також публікацією їх npmта імпортом їх за допомогою javascriptабоtypescript

Цей модуль написано з використанням, typescript 2.2і важливо налаштувати prepublishгачок для складання коду за допомогоюtsc перш ніж публікувати його в npm

https://github.com/sweetim/haversine-position

https://www.npmjs.com/package/haversine-position


1
Це дуже корисний приклад, дякую за обмін! Наразі я також намагаюся розібратися у створенні пакетів таким чином.
Джефрі Вестеркамп

1
Станом на липень 2017 року, це найкраща структура проекту, на яку я потрапив. Спасибі Тіму та
Варуну

3

Ви можете використовувати автозаписи для обробки розповсюдження та використання .d.tsфайлів з npm також без підтримки Atom IDE.

autodts generateз'єднає всі ваші власні .d.tsфайли разом для публікації в npm та autodts linkобробляє посилання на інші встановлені пакети, які не завжди можуть бути безпосередньо під node_modulesчас більшого проекту, розділеного на кілька підпакетів.

Обидві команди читають їхні налаштування з package.jsonта tsconfig.jsonв стилі "умова щодо конфігурації".

Є ще одна відповідь на stackoverflow та публікація в блозі з додатковими подробицями.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.