לדלג לתוכן

4.9 Node.js, npm וכלי פיתוח הרצאה

מה זה Node.js

Node.js הוא סביבת הרצה (runtime) לג'אווהסקריפט מחוץ לדפדפן.

  • בנוי על מנוע V8 של Chrome
  • מאפשר להריץ JS על המחשב, לא רק בדפדפן
  • משמש לבניית שרתים, כלי פיתוח, סקריפטים ועוד
  • מגיע עם npm - מנהל חבילות (package manager)

התקנה

הורידו מ-https://nodejs.org את גרסת LTS (Long Term Support).

בדיקה שההתקנה הצליחה:

node --version   # v20.x.x
npm --version    # 10.x.x


הרצת קבצים

# create a file
echo 'console.log("Hello from Node!")' > hello.js

# run it
node hello.js
# Hello from Node!

ב-Node אין document, window, או alert - אלה API-ים של הדפדפן. במקום זה יש API-ים של מערכת ההפעלה:

// file system
const fs = require("fs");
const content = fs.readFileSync("hello.js", "utf-8");
console.log(content);

// path
const path = require("path");
console.log(path.join(__dirname, "hello.js"));

אובייקט process

process הוא אובייקט גלובלי ב-Node שמספק מידע על התהליך הנוכחי:

// command line arguments
console.log(process.argv); // ["node", "script.js", "arg1", "arg2"]

// environment variables
console.log(process.env.PATH);
console.log(process.env.NODE_ENV); // "development" or "production"

// current directory
console.log(process.cwd());

// exit the process
process.exit(0); // 0 = success, 1 = error
# pass arguments
node script.js hello world
# process.argv = ["node", "script.js", "hello", "world"]

# set environment variables
NODE_ENV=production node script.js

REPL

REPL (Read-Eval-Print Loop) הוא מצב אינטראקטיבי שבו אפשר לכתוב JS ולקבל תוצאות מיד:

node
# opens REPL

> 2 + 3
5
> const arr = [1, 2, 3]
undefined
> arr.map(n => n * 2)
[ 2, 4, 6 ]
> .exit

שימושי לניסויים מהירים, כמו הקונסולה בדפדפן.


npm - מנהל חבילות

npm (Node Package Manager) הוא הכלי לניהול חבילות (packages/libraries) בפרויקטי JS.

  • מגיע מותקן יחד עם Node.js
  • מאפשר להתקין, לעדכן ולמחוק חבילות
  • מנהל תלויות (dependencies) של הפרויקט
  • Registry עם מיליוני חבילות: https://www.npmjs.com

אתחול פרויקט - npm init

# create a new project
mkdir my-project
cd my-project

# initialize package.json
npm init

# or skip all questions with defaults
npm init -y

הפקודה יוצרת קובץ package.json - זה הקובץ המרכזי שמתאר את הפרויקט:

{
    "name": "my-project",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC"
}

התקנת חבילות - npm install

# install a package (adds to dependencies)
npm install lodash

# shorthand
npm i lodash

# install as dev dependency (only for development)
npm install --save-dev eslint
npm i -D eslint

# install globally (available everywhere)
npm install -g nodemon

# install all dependencies from package.json
npm install

אחרי התקנה:
- החבילה נשמרת בתיקיית node_modules/
- package.json מתעדכן עם שם החבילה והגרסה
- package-lock.json נוצר - נועל את הגרסאות המדויקות של כל התלויות

חשוב לגבי node_modules

  • תיקיית node_modules לא עולה ל-git - היא בדרך כלל ב-.gitignore
  • כשמורידים פרויקט מ-git, מריצים npm install כדי להתקין את כל התלויות
  • לא עורכים קבצים בתוך node_modules ידנית
// using an installed package
const _ = require("lodash"); // CommonJS (Node default)

// or with ES modules
import _ from "lodash";

סקריפטים - npm scripts

ב-package.json אפשר להגדיר סקריפטים:

{
    "scripts": {
        "start": "node server.js",
        "dev": "node --watch server.js",
        "build": "vite build",
        "lint": "eslint src/",
        "test": "jest"
    }
}
# run scripts
npm start        # special - no "run" needed
npm test         # special - no "run" needed
npm run dev      # custom scripts need "run"
npm run build
npm run lint
  • start ו-test הם סקריפטים מיוחדים שלא צריכים run
  • סקריפטים מותאמים צריכים npm run <name>
  • סקריפטים יכולים להשתמש בחבילות שמותקנות מקומית (בלי להתקין גלובלית)

npx - הרצה ללא התקנה

npx מריץ חבילות בלי להתקין אותן גלובלית:

# instead of installing globally:
npm install -g create-vite
create-vite my-app

# just use npx:
npx create-vite my-app

# run a locally installed package
npx eslint src/
  • מוריד את החבילה באופן זמני ומריץ אותה
  • שימושי ל-scaffolding tools (create-vite, create-react-app)
  • שימושי להרצת כלים שלא צריך להתקין לצמיתות

גרסאות - Semantic Versioning

חבילות npm משתמשות ב-semver (Semantic Versioning):

MAJOR.MINOR.PATCH
  3  .  2  .  1
  • MAJOR - שינויים שוברים (breaking changes). קוד שעבד עם 2.x לא בהכרח יעבוד עם 3.x
  • MINOR - תכונות חדשות שלא שוברות תאימות
  • PATCH - תיקוני באגים

ב-package.json:
- "lodash": "4.17.21" - גרסה מדויקת
- "lodash": "^4.17.21" - כל גרסה 4.x.x (minor ו-patch יכולים להתעדכן)
- "lodash": "~4.17.21" - כל גרסה 4.17.x (רק patch יכול להתעדכן)

^ (caret) הוא ברירת המחדל כש-npm מתקין - מאפשר עדכוני minor ו-patch.


Vite - כלי בנייה

Vite הוא כלי בנייה (build tool) מודרני ומהיר לפרויקטי פרונטאנד.

למה צריך כלי בנייה:
- מאפשר import/export (ES Modules) שעובד בכל הדפדפנים
- ממיר קוד מודרני לקוד תואם דפדפנים ישנים
- מאגד (bundle) הרבה קבצים לקובץ אחד או כמה קבצים קטנים
- ממזער (minify) את הקוד לטעינה מהירה
- טוען CSS, תמונות וקבצים אחרים כחלק מהפרויקט

יצירת פרויקט חדש עם Vite

npm create vite@latest my-app
# choose: Vanilla (or React, Vue, etc.)
# choose: JavaScript

cd my-app
npm install
npm run dev

מבנה הפרויקט:

my-app/
  index.html          # entry point
  package.json
  vite.config.js      # Vite configuration
  src/
    main.js           # main JS file
    style.css
  public/             # static files (copied as-is)


החלפה חמה - HMR

HMR (Hot Module Replacement) הוא מנגנון שמאפשר לעדכן קוד בדפדפן בלי לרענן את הדף:

  • כששומרים קובץ, Vite שולח רק את השינויים לדפדפן
  • ה-state נשמר (למשל מה שהמשתמש הקליד בטופס)
  • זה עובד אוטומטית ב-Vite - אין צורך בהגדרות
# start dev server with HMR
npm run dev
# Local: http://localhost:5173/

כל שינוי בקובץ מתעדכן מיד בדפדפן, בלי רענון ובלי אובדן state.


בנייה לייצור - Build

# build for production
npm run build

הפקודה יוצרת תיקיית dist/ עם הקבצים המוכנים לייצור:
- JS ממוזער (minified)
- CSS ממוזער
- תמונות מותאמות
- HTML עם הפניות לקבצים הסופיים

# preview the build locally
npm run preview

הגדרות ב-vite.config.js

import { defineConfig } from "vite";

export default defineConfig({
    // dev server settings
    server: {
        port: 3000,
        open: true // open browser automatically
    },

    // build settings
    build: {
        outDir: "dist",
        sourcemap: true // generate source maps
    },

    // path alias
    resolve: {
        alias: {
            "@": "/src"
        }
    }
});

משתני סביבה - Environment Variables

Vite תומך במשתני סביבה דרך קבצי .env:

# .env - loaded in all cases
VITE_API_URL=https://api.example.com

# .env.development - only in dev
VITE_API_URL=http://localhost:3001

# .env.production - only in production build
VITE_API_URL=https://api.production.com
// access in code (must start with VITE_)
console.log(import.meta.env.VITE_API_URL);
console.log(import.meta.env.MODE); // "development" or "production"
console.log(import.meta.env.DEV);  // true in dev
console.log(import.meta.env.PROD); // true in production
  • רק משתנים שמתחילים ב-VITE_ חשופים בקוד הלקוח
  • משתנים רגישים (סודות, מפתחות API סודיים) לא שמים בקוד הלקוח
  • קבצי .env לא עולים ל-git (מוסיפים .env ל-.gitignore)

ESLint - בדיקת קוד

ESLint הוא כלי שמנתח את הקוד ומצביע על בעיות ושגיאות פוטנציאליות:

# install
npm i -D eslint

# initialize configuration
npx eslint --init

ESLint יוצר קובץ הגדרות (eslint.config.js או .eslintrc.json) שמגדיר חוקים:

// eslint.config.js (flat config - new format)
export default [
    {
        rules: {
            "no-unused-vars": "warn",     // warn on unused variables
            "no-console": "off",          // allow console.log
            "eqeqeq": "error",           // require === instead of ==
            "no-var": "error"             // require let/const instead of var
        }
    }
];
# run ESLint
npx eslint src/

# fix auto-fixable issues
npx eslint src/ --fix
  • "error" - עוצר את הבנייה
  • "warn" - מציג אזהרה אבל לא עוצר
  • "off" - מבטל את הכלל

Prettier - עיצוב קוד

Prettier הוא כלי שמפרמט (מעצב) קוד באופן אוטומטי:

# install
npm i -D prettier

# create configuration
echo '{}' > .prettierrc
// .prettierrc
{
    "semi": true,
    "singleQuote": false,
    "tabWidth": 4,
    "trailingComma": "none",
    "printWidth": 100
}
# format files
npx prettier --write src/

# check without changing
npx prettier --check src/

שילוב ESLint ו-Prettier

כדי למנוע התנגשויות בין ESLint ל-Prettier:

npm i -D eslint-config-prettier
// eslint.config.js
import prettierConfig from "eslint-config-prettier";

export default [
    // your rules...
    prettierConfig // must be last - disables conflicting ESLint rules
];

שילוב ב-package.json

{
    "scripts": {
        "dev": "vite",
        "build": "vite build",
        "preview": "vite preview",
        "lint": "eslint src/",
        "lint:fix": "eslint src/ --fix",
        "format": "prettier --write src/"
    }
}

סיכום

  • Node.js - סביבת הרצה ל-JS מחוץ לדפדפן, כולל גישה למערכת קבצים ו-process
  • npm - מנהל חבילות. npm init ליצירת פרויקט, npm install להתקנת חבילות
  • package.json - מתאר את הפרויקט, תלויות וסקריפטים
  • npx - הרצת חבילות ללא התקנה גלובלית
  • semver - MAJOR.MINOR.PATCH, ^ מאפשר עדכוני minor
  • Vite - כלי בנייה מהיר. dev server עם HMR, build לייצור
  • משתני סביבה - קבצי .env עם קידומת VITE_
  • ESLint - מצביע על בעיות בקוד
  • Prettier - מפרמט קוד באופן אחיד