עבודה עם TypeScript בפרויקט Node.JS

בעבודה על פרויקט Node.JS הבחירה בטייפסקריפט תוסיף אומנם עוד רמה אחת של סיבוך לפרויקט, כי אני צריך להפוך את הקבצים שלי מ TypeScript ל JavaScript לפני ההרצה, אבל התמורה שמקבלים עדיין שווה את זה. בואו נראה איך להוסיף טייפסקריפט לפרויקט Node.JS.

1. יצירת פרויקט Node.JS חדש עם טייפסקריפט

בניגוד לפרויקטי צד לקוח בהם אנחנו רגילים "לקמפל" את הקוד שלנו עם וובפאק או בייבל, בעבודה עם Node.JS אנחנו רגילים לכתוב קוד בקובץ עם סיומת .js ופשוט להריץ אותו. המעבר לטייפסקריפט מחייב אותנו ללמוד שיטת עבודה חדשה ולהוסיף עוד כלי בדרך:

  1. אנחנו נכתוב קוד TypeScript בקבצים עם סיומת ts.

  2. הקומפיילר של טייפסקריפט יהפוך אותם לקבצי JavaScript, ובדרך יבדוק את תקינות הטיפוסים.

  3. אנחנו נפעיל node.js כדי להריץ את קבצי ה JavaScript שהקומפיילר יצר.

זה תהליך יותר מסובך וכן יש יותר מקום לטעויות. אני מקווה להראות בשיעור זה שזה לא יותר מדי מסובך, ושאפשר לקבל החזר טוב על ההשקעה.

בשביל ליצור פרויקט Node.JS חדש אני יוצר תיקיה חדשה, ובתוכה כותב:

$ npm init -y

בשביל להוסיף לפרויקט תמיכה ב TypeScript אני אצטרך להתקין מספר ספריות:

$ npm install --save-dev typescript ts-node @types/node

בנוסף אני רוצה להתקין קובץ הגדרות TypeScript בסיסי שמתאים לגירסת ה Node איתה אני עובד. אני מריץ:

$ node --version

ומגלה את הגירסה שמותקנת אצלי על המכונה (בדוגמה שלי זו 16, אצלכם אולי הגירסה שונה). אחרי זה אני מפעיל:

$ npm install --save-dev @tsconfig/node16

ויוצר קובץ חדש בשם tsconfig.json עם התוכן הבא:

{
    "extends": "@tsconfig/node16/tsconfig.json"
}

ועכשיו אנחנו מוכנים להתחיל לקודד. ניצור קובץ בשם main.ts עם התוכן הבא:

function sayHi(name: string) {
  console.log(`Hello ${name}`);
}

sayHi('ynon');

ונראה ש VS Code מספק את כל הוולידציות וההשלמות האוטומטיות שאנחנו צריכים. עכשיו בואו נראה איך מריצים אותו.

2. הגדרת ts-node כדי להריץ בצורה מיידית במצב פיתוח

הצעד הבא הוא פשוט להריץ את הקובץ ובשביל זה אני משתמש בכלי נוסף שנקרא ts-node. בדרך כלל Node.JS יודע להריץ רק קבצי JavaScript, אבל ts-node הוא גירסה של node שאוטומטית בעלייה הופכת את קבצי ה TypeScript שקיבלה לקבצי JavaScript (הכל בזיכרון, הקבצים לא נכתבים) ואז מריצה אותם. זה קיצור דרך נחמד למצב פיתוח בו אני לא רוצה כל פעם לבנות מחדש את הפרויקט.

אני מתקין את ts-node עם:

$ npm install --save-dev ts-node

ועכשיו יכול להריץ עם:

$ npx ts-node main.ts

יהיה נחמד גם לעדכן את ה package.json ולהוסיף סקריפט שמריץ אוטומטית את הקובץ, לכן אני מוסיף את הסקריפט הבא:

  "scripts": {
    "dev": "ts-node main.ts",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

ועכשיו אפשר להפעיל עם:

npm run dev

בשביל המשחק בואו נראה של ts-node אין בעיה כשהתוכנית שלנו מחולקת למספר קבצים: אני מוציא את הפונקציה לקובץ נפרד בשם utils.ts, מוסיף ל main פקודת import ורואה שהכל עדיין עובד.

3. מעבר למצב Production

במצב Production אנחנו רוצים להפוך את כל קבצי ה ts ל js לפני שמריצים כדי לא להעמיס על השרת. הכלי tsc הוא הקומפיילר של טייפסקריפט, והוא פשוט לוקח את כל מבנה התיקיות של הפרויקט ומתרגם כל קובץ TypeScript לקובץ JavaScript שמתאים לו. אני מריץ עם:

$ npx tsc

ומקבל את שני הקבצים main.js ו utils.js. מבט לתוך הקובץ main.js שנוצר מראה לי שטייפסקריפט תרגם את פקודות ה import/export שאני כתבתי לפקודות require של Node.JS:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
(0, utils_1.sayHi)('ynon');

בשביל שיהיה נוח לעבוד עם הפרויקט אני מוסיף את tsc בתור סקריפט נוסף ל package.json ומקבל שם:

"scripts": {
  "dev": "ts-node main.ts",
  "build": "tsc",
  "test": "echo \"Error: no test specified\" && exit 1"
},

הרבה פעמים אנחנו מעדיפים שקבצי ה JavaScript לא יווצרו לתוך תיקיית הפרויקט כדי שנוכל להעתיק אותם בנפרד לשרת וכי זה פחות מבלבל ככה. אפשר לבקש מ tsc ליצור אותם במקום נפרד באמצעות שינוי בקובץ tsconfig.json. נכנס לקובץ ונוסיף את השורות:

{
  "extends": "@tsconfig/node16/tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist"
  }
}

ועכשיו כשאני מריץ בניה מחדש הקבצים יישמרו לתוך תיקיית dist.