การเขียนโมดูล NPM ใน typescript


103

ฉันกำลังทำงานกับโมดูล NPM แรกของฉัน ฉันทำงานกับ typescript มาก่อนสั้น ๆ และปัญหาใหญ่คือสำหรับหลายโมดูลไม่มีไฟล์นิยาม ดังนั้นฉันจึงคิดว่าจะเป็นการดีที่จะเขียนโมดูลของฉันเป็น typescript

อย่างไรก็ตามฉันไม่พบข้อมูลเกี่ยวกับวิธีที่ดีที่สุดในการดำเนินการดังกล่าว ฉันพบคำถามที่เกี่ยวข้องนี้ " ฉันสามารถเขียนแพ็คเกจ npm ในกาแฟได้หรือไม่ " ซึ่งมีคนแนะนำให้เผยแพร่เฉพาะไฟล์จาวาสคริปต์เท่านั้น แต่ในทางตรงกันข้ามกับไฟล์ Coffeescript ไฟล์ typescript อาจมีประโยชน์หากใช้ในแอปพลิเคชัน typescript

ฉันควรรวมไฟล์ typescript เมื่อเผยแพร่โมดูล NPM หรือฉันควรเผยแพร่เฉพาะไฟล์ javascript และจัดเตรียมไฟล์. d.ts ที่สร้างขึ้นให้กับ DefinelyTyped


2
หมายเหตุที่เป็นประโยชน์: ฉันเขียนโครงการcopeeพร้อมกับบล็อกโพสต์เพื่อแนะนำคุณตลอดการตั้งค่าโครงการ TS เพื่อปล่อยคำจำกัดความประเภทพร้อมกับเป้าหมาย CJS และ ESM ก่อนที่จะเผยแพร่ไปยัง npm สิ่งนี้จะเพิ่มการใช้งานกับ node.js และเบราว์เซอร์ให้มากที่สุดต่อไป
styfle

คำตอบ:


84

นี่คือตัวอย่างโมดูลโหนดที่เขียนใน TypeScript: https://github.com/basarat/ts-npm-module

นี่คือตัวอย่างโครงการ TypeScript ที่ใช้โมดูลตัวอย่างนี้https://github.com/basarat/ts-npm-module-consume

โดยทั่วไปคุณต้อง:

  • รวบรวมด้วยcommonjsและdeclaration:true
  • สร้าง.d.tsไฟล์

แล้ว

  • ได้ IDE .d.tsของคุณอ่านที่สร้างขึ้น

Atom-TypeScript มีขั้นตอนการทำงานที่ดีสำหรับสิ่งนี้: https://github.com/TypeStrong/atom-typescript#packagejson-support


ต้องอัปเดตลิงก์จุดยึด Atom-TypeScript (จุดยึดไม่ถูกต้องอีกต่อไป)
Fidan Hakaj

@basarat ในโมดูล ts-npm คุณกำลังใช้ "version": "1.5.0-alpha" ฉันคิดว่านี่เป็นเวอร์ชันของ typescript ที่คุณกำลังถ่ายทอดด้วย มันสำคัญหรือไม่ที่จะปล่อยสิ่งนี้ออกไป (ปลั๊กอิน Atom ไม่ได้ทำโดยอัตโนมัติ) หากมีการใช้เวอร์ชันสิ่งนี้จะต้องให้ผู้ใช้รายอื่นใช้เวอร์ชันที่แน่นอนในการแปลงไฟล์ (หรือเวอร์ชันใหม่กว่าเท่านั้น) (หรืออาจจะเป็นเวอร์ชั่นของ tsconfig.json?)
justin

คุณมีกรณีการใช้งานกับโมดูลที่ขึ้นอยู่กับไลบรารีอื่น ๆ หรือไม่? เพื่อหลีกเลี่ยงปัญหาคำจำกัดความที่ซ้ำกันคุณต้องกำหนดค่าtsconfig.jsonแต่ดูเหมือนว่าเป็นคู่มือเกินไปในความคิดของฉัน
Sérgio Michels

1
คุณยังจะสนับสนุนแนวทางนี้ในไตรมาสที่ 4 ปี 2559 หรือไม่
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ชี้ไปที่ typings สร้างของคุณ ตัวอย่างเช่นถ้า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)

เนื่องจากทำให้ฉันต้องค้นหาแหล่งข้อมูลที่ล้าสมัยทั้งหมดในหัวข้อนี้บนอินเทอร์เน็ต (เช่นเดียวกับในหน้านี้ ... ) ฉันจึงตัดสินใจที่จะสรุปมันในไลบรารีวิธีการเขียน a-typescriptด้วย ตัวอย่างขั้นต่ำในการทำงานที่ทันสมัย


ฉันจะต้องตรวจสอบ js ในการควบคุมแหล่งที่มาหรือไม่ หรือ npm เก็บรหัสเวอร์ชันของตัวเองไว้?
Olian04

1
@ Olian04 คุณบอกให้สร้าง.npmignoreไฟล์เพื่อบอก npm ว่าไฟล์ใดที่จะเพิกเฉยเมื่อเผยแพร่ ( .tsไฟล์) และ.gitignoreบอกคอมไพล์ว่าไฟล์ใดที่จะละเว้น ( dist/)
Purag

@ Olian04 ไม่คุณไม่จำเป็นต้อง (และ IMO ไม่ควร) คอมมิตไฟล์ JS ที่สร้างขึ้น สิ่งเหล่านี้ไม่ได้เป็นส่วนหนึ่งของแหล่งที่มาของโครงการ
Josh M.

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:ฉันเชื่อว่าวิธีการรวบรวมโปรเจ็กต์เป็นโมดูล npm ซึ่งสามารถใช้ในโปรเจ็กต์อื่น ๆ นั้นชวนให้นึกถึง.dllใน.NETโลกนี้ ฉันสามารถจินตนาการได้ดีว่าโครงการที่จัดในโซลูชันใน VS Code ซึ่งแต่ละโครงการจะสร้างแพ็คเกจ npm ซึ่งสามารถใช้ในโปรเจ็กต์อื่นในโซลูชันเป็นการพึ่งพาได้

เนื่องจากฉันใช้เวลาพอสมควรในการคิดออกฉันจึงโพสต์ไว้เผื่อว่ามีคนติดอยู่ที่นี่

ฉันโพสต์ไว้เพื่อปิดข้อบกพร่องที่: https://github.com/npm/npm/issues/11546


ตัวอย่างนี้อัปโหลดไปยัง Github: vchatterji / tsc-seed


คุณช่วยอัพโหลดตัวอย่างบน github ได้ไหม นั่นจะช่วยได้มาก! :)
Han Che

3
ตัวอย่างถูกอัปโหลดไปยัง Github: github.com/vchatterji/tsc-seed
Varun Chatterji

ยังสามารถใช้ในโครงการที่ไม่ใช่ typescript ได้อย่างไร
SuperUberDuper

5

คุณควรเผยแพร่แหล่งที่มาของ typescript ดั้งเดิมแทนการกำหนดประเภท ในการpackage.jsonให้คุณสมบัติ 'types' ชี้ไปที่ไฟล์ * .ts

*.d.ts เป็นสิ่งที่ดีในการใส่คำอธิบายประกอบ JS libs ที่มีอยู่ แต่ในฐานะผู้บริโภคฉันอยากอ่านโค้ด typescript มากกว่าการสลับระหว่างคำจำกัดความประเภทและโค้ด JS ที่สร้างขึ้นในระดับลง


1
ดูเหมือนว่าคอมไพลเลอร์ TypeScript จะไม่เหมาะสำหรับสิ่งนั้นจนถึงตอนนี้ ดูฉบับนี้ที่github.com/Microsoft/TypeScript/issues/14479
Sven Efftinge

2
รวมถึง*.d.tsเป็นวิธีที่แนะนำในขณะนี้แม้ว่าฉันจะเห็นด้วยกับประโยชน์ของคุณในการรวม*.tsไฟล์typescriptlang.org/docs/handbook/declaration-files/…
Tim

5

ฉันทำตามคำแนะนำของVarun Chatterji เป็นหลัก

แต่ฉันต้องการแสดงตัวอย่างที่สมบูรณ์พร้อมการทดสอบหน่วยและการครอบคลุมโค้ดและเผยแพร่npmและนำเข้าโดยใช้javascriptหรือtypescript

โมดูลนี้เขียนขึ้นโดยใช้typescript 2.2และเป็นสิ่งสำคัญในการกำหนดค่าprepublishhook เพื่อรวบรวมโค้ดโดยใช้tscก่อนที่จะเผยแพร่ไปยัง npm

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

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


1
เป็นตัวอย่างที่มีประโยชน์มากขอบคุณสำหรับการแบ่งปัน! ฉันกำลังพยายามที่จะสร้างแพ็คเกจในรูปแบบนี้
Jeffrey Westerkamp

1
เมื่อเดือนกรกฎาคม 2017 นี่เป็นโครงสร้างโครงการที่ดีที่สุดที่ฉันเจอ ขอบคุณ Tim และ Varun Chatterji
adgang

3

คุณสามารถใช้autodtsเพื่อจัดการการแจกจ่ายและการใช้.d.tsไฟล์จาก npm โดยไม่ต้องรองรับ Atom IDE

autodts generateจะ.d.tsรวมไฟล์ของคุณเองทั้งหมดเข้าด้วยกันเพื่อเผยแพร่บน npm และautodts linkจัดการการอ้างอิงไปยังแพ็กเกจอื่น ๆ ที่ติดตั้งไว้ซึ่งอาจไม่ได้อยู่node_modulesในโปรเจ็กต์ขนาดใหญ่โดยตรงโดยแบ่งออกเป็นแพ็กเกจย่อยหลาย ๆ แพ็กเกจ

คำสั่งทั้งสองอ่านการตั้งค่าจากpackage.jsonและtsconfig.jsonในสไตล์ "convention over configuration"

มีคำตอบอื่นเกี่ยวกับ stackoverflow และบล็อกโพสต์พร้อมรายละเอียดเพิ่มเติม


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.