npm چیست؟ آموزش کامل npm، package.json و ساخت پکیج JavaScript برای API هوش مصنوعی

در این آموزش npm را از صفر تا سطح کاربردی یاد می‌گیرید؛ از نصب Package و مدیریت package.json تا package-lock، Scripts، SemVer و Workspaces. در پایان یک پکیج JavaScript قابل‌استفاده مجدد برای API هوش مصنوعی درواره می‌سازیم.

Share
npm چیست؟ آموزش کامل npm، package.json و ساخت پکیج JavaScript برای API هوش مصنوعی

اگر با JavaScript، Node.js، React، Next.js، Vue یا بسیاری از ابزارهای توسعه وب کار کرده باشید، احتمالاً دستورهایی مانند npm install، npm run dev و npm start را دیده‌اید.

npm فقط ابزاری برای دانلود کتابخانه نیست. این ابزار در بخش‌های مختلف چرخه توسعه JavaScript نقش دارد:

  • ایجاد پروژه
  • نصب و حذف Package
  • مدیریت نسخه وابستگی‌ها
  • اجرای Scriptهای پروژه
  • ساخت فایل Lock
  • اجرای ابزارهای خط فرمان
  • مدیریت Monorepo
  • بسته‌بندی و انتشار Package
  • نصب قابل‌تکرار در CI/CD

در این آموزش مفاهیم npm را از پایه یاد می‌گیریم و سپس یک پروژه واقعی می‌سازیم: یک Package قابل‌استفاده مجدد JavaScript برای اتصال برنامه‌های Node.js به API هوش مصنوعی درواره.

npm چیست؟

npm مجموعه‌ای از ابزارها و سرویس‌ها برای مدیریت Packageهای JavaScript است.

طبق مستندات رسمی npm، npm از سه بخش اصلی تشکیل شده است:

  • وب‌سایت npm
  • ابزار خط فرمان npm CLI
  • Registry یا مخزن Packageها

وب‌سایت npm برای جست‌وجو و بررسی Packageها استفاده می‌شود. Registry محل نگهداری Packageها و Metadata آن‌ها است. npm CLI ابزاری است که از Terminal برای نصب، حذف، به‌روزرسانی، اجرا و مدیریت Packageها استفاده می‌کنیم.

npm مخفف چیست؟

npm معمولاً با عبارت Node Package Manager شناخته می‌شود؛ زیرا در اکوسیستم Node.js برای مدیریت Packageها استفاده می‌شود.

بااین‌حال، در استفاده عملی مهم‌تر از نام کامل آن، سه نقش اصلی npm است:

Package Manager
Package Registry
Command-line Tool

Package چیست؟

Package مجموعه‌ای از فایل‌ها و Metadata است که یک قابلیت مشخص را ارائه می‌دهد.

یک Package می‌تواند شامل این موارد باشد:

  • تابع JavaScript
  • React Component
  • ابزار Build
  • کتابخانه اتصال به API
  • ابزار خط فرمان
  • Plugin
  • Type Definition
  • فایل CSS
  • مجموعه تنظیمات
  • Framework

نمونه Packageهای شناخته‌شده:

express
react
typescript
vite
dotenv
eslint

Package الزاماً نباید عمومی باشد. یک شرکت می‌تواند Packageهای داخلی و خصوصی برای اشتراک کد میان پروژه‌های خود داشته باشد.

Module چیست؟

در JavaScript، Module فایلی است که کد را Export می‌کند تا فایل‌های دیگر بتوانند آن را Import کنند.

فایل math.js:

export function add(first, second) {
  return first + second;
}

فایل app.js:

import { add } from "./math.js";

console.log(add(10, 5));

یک Package می‌تواند شامل یک یا چند Module باشد.

تفاوت مفهومی:

Module = واحد کد قابل Import
Package = مجموعه فایل‌ها و Metadata قابل نصب

npm همراه Node.js نصب می‌شود؟

در بیشتر روش‌های رسمی نصب Node.js، npm نیز همراه آن نصب می‌شود.

بررسی نسخه Node.js:

node --version

بررسی نسخه npm:

npm --version

اگر نسخه نمایش داده شود، npm نصب است.

برای نصب یا به‌روزرسانی بهتر است روش مناسب سیستم‌عامل و مستندات نسخه فعلی Node.js و npm را بررسی کنید. در محیط‌های توسعه حرفه‌ای، استفاده از Version Manager می‌تواند مدیریت چند نسخه Node.js را ساده‌تر کند.

Registry در npm چیست؟

Registry یک پایگاه Package است. هنگام اجرای دستور زیر:

npm install express

npm اطلاعات Package و وابستگی‌های آن را از Registry دریافت و در پروژه نصب می‌کند.

Registry عمومی پیش‌فرض:

https://registry.npmjs.org/

مشاهده Registry فعلی:

npm config get registry

شرکت‌ها می‌توانند Registry خصوصی نیز داشته باشند، اما برای بیشتر پروژه‌های عمومی همان Registry پیش‌فرض استفاده می‌شود.

ایجاد اولین پروژه npm

یک پوشه جدید بسازید:

mkdir npm-demo
cd npm-demo

سپس:

npm init

npm چند سؤال درباره نام، نسخه، توضیحات و Entry Point پروژه می‌پرسد.

برای ایجاد سریع با مقدارهای پیش‌فرض:

npm init -y

پس از اجرا، فایل package.json ایجاد می‌شود.

package.json چیست؟

package.json فایل اصلی Metadata و تنظیمات پروژه npm است.

نمونه:

{
  "name": "npm-demo",
  "version": "1.0.0",
  "description": "A simple npm project",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "node --test"
  },
  "keywords": [
    "javascript",
    "nodejs"
  ],
  "author": "",
  "license": "MIT"
}

براساس مرجع package.json در مستندات npm، این فایل باید JSON معتبر باشد، نه JavaScript Object.

بنابراین موارد زیر در package.json مجاز نیستند:

  • کامنت
  • Comma اضافی
  • تابع
  • متغیر
  • عبارت JavaScript
  • کلید بدون Double Quote

این JSON نامعتبر است:

{
  // comment is not allowed
  "name": "my-project",
}

نسخه معتبر:

{
  "name": "my-project"
}

مهم‌ترین فیلدهای package.json

name

نام Package یا پروژه:

{
  "name": "darvareh-client"
}

نام باید با قواعد npm سازگار باشد. برای Package عمومی باید یکتا باشد.

version

نسخه Package:

{
  "version": "1.0.0"
}

نسخه معمولاً از Semantic Versioning پیروی می‌کند.

description

{
  "description": "JavaScript client for an AI API"
}

private

اگر Package نباید تصادفی منتشر شود:

{
  "private": true
}

این فیلد برای اپلیکیشن‌ها و Packageهای داخلی مفید است.

type

برای استفاده از ECMAScript Modules:

{
  "type": "module"
}

در این حالت می‌توان نوشت:

import express from "express";

بدون تنظیم type: module، رفتار فایل‌های .js ممکن است براساس CommonJS باشد:

const express = require("express");

main

Entry Point قدیمی و رایج Package:

{
  "main": "./src/index.js"
}

برای Packageهای جدید می‌توان از exports نیز استفاده کرد.

exports

مسیرهای عمومی Package را کنترل می‌کند:

{
  "exports": {
    ".": "./src/index.js"
  }
}

اگر Package چند ورودی داشته باشد:

{
  "exports": {
    ".": "./src/index.js",
    "./errors": "./src/errors.js"
  }
}

files

مشخص می‌کند هنگام بسته‌بندی چه فایل‌هایی وارد Package شوند:

{
  "files": [
    "src",
    "README.md"
  ]
}

scripts

Commandهای پروژه:

{
  "scripts": {
    "start": "node src/index.js",
    "dev": "node --watch src/index.js",
    "test": "node --test"
  }
}

engines

نسخه Runtime مورد انتظار:

{
  "engines": {
    "node": ">=20"
  }
}

این فیلد نیازمندی پروژه را اعلام می‌کند. سخت‌گیرانه‌بودن اجرای آن می‌تواند به تنظیمات npm وابسته باشد.

license

مجوز Package:

{
  "license": "MIT"
}

برای Package خصوصی سازمانی ممکن است از مقدار زیر استفاده شود:

{
  "license": "UNLICENSED"
}

انتخاب License باید آگاهانه و متناسب با نحوه انتشار انجام شود.

dependencies چیست؟

Packageهایی که برنامه برای اجرا به آن‌ها نیاز دارد در dependencies قرار می‌گیرند:

{
  "dependencies": {
    "express": "^5.0.0",
    "dotenv": "^17.0.0"
  }
}

نصب:

npm install express

npm به‌صورت پیش‌فرض Package را در dependencies ثبت می‌کند.

devDependencies چیست؟

ابزارهایی که فقط برای توسعه، تست، Lint یا Build لازم هستند در devDependencies قرار می‌گیرند:

{
  "devDependencies": {
    "eslint": "^9.0.0",
    "vitest": "^3.0.0"
  }
}

نصب:

npm install --save-dev eslint

نسخه کوتاه:

npm install -D eslint

نمونه Dev Dependency:

  • Linter
  • Formatter
  • Test Runner
  • Bundler
  • Type Checker
  • ابزار Build
  • ابزار Development Server

تفاوت dependencies و devDependencies

موضوعdependenciesdevDependencies
نیاز در Runtimeبلهمعمولاً خیر
ابزار تستمعمولاً خیربله
کتابخانه Backendبلهخیر
Build Toolبسته به معماریمعمولاً بله
ثبت در package.jsonبلهبله

برای یک Package کتابخانه‌ای، Dependencyهای Runtime کاربران Package باید با دقت انتخاب شوند؛ زیرا به پروژه مصرف‌کننده اضافه خواهند شد.

peerDependencies چیست؟

peerDependencies اعلام می‌کند Package انتظار دارد پروژه مصرف‌کننده نسخه‌ای سازگار از یک Package دیگر داشته باشد.

مثال یک Plugin برای React:

{
  "peerDependencies": {
    "react": ">=18"
  }
}

این الگو زمانی مفید است که Package نباید نسخه جداگانه و مستقل از Dependency میزبان نصب کند.

موارد رایج:

  • Plugin فریم‌ورک
  • React Component Library
  • ESLint Plugin
  • Adapter
  • Extension یک کتابخانه

optionalDependencies چیست؟

Dependency اختیاری می‌تواند در صورت نصب‌نشدن، مانع کل نصب نشود:

{
  "optionalDependencies": {
    "some-optional-package": "^1.0.0"
  }
}

برنامه باید نبودن این Dependency را مدیریت کند.

نصب Package با npm install

نصب تمام Dependencyهای ثبت‌شده:

npm install

نسخه کوتاه:

npm i

نصب Package:

npm install express

نصب نسخه مشخص:

npm install express@5.0.0

نصب Development Dependency:

npm install -D eslint

نصب Package محلی:

npm install ../my-local-package

نصب از فایل بسته‌بندی‌شده:

npm install ./my-package-1.0.0.tgz

جزئیات حالت‌های نصب در مستندات npm install ارائه شده است.

node_modules چیست؟

npm Packageهای نصب‌شده را معمولاً داخل پوشه node_modules قرار می‌دهد:

project/
├── node_modules/
├── package.json
└── package-lock.json

این پوشه ممکن است تعداد زیادی فایل داشته باشد؛ زیرا Dependencyهای مستقیم شما نیز Dependencyهای دیگری دارند.

ساختار مفهومی:

پروژه شما
├── express
│   ├── dependency-a
│   └── dependency-b
└── another-package
    └── dependency-c

آیا node_modules را وارد Git کنیم؟

معمولاً خیر.

فایل .gitignore:

node_modules/
.env
coverage/
dist/

دلایل:

  • حجم زیاد
  • قابل‌بازتولید بودن با npm
  • تفاوت‌های سیستم‌عامل
  • تغییر دائمی فایل‌ها
  • وجود package.json و Lock File

پس از Clone کردن پروژه:

npm install

یا در محیط CI:

npm ci

package-lock.json چیست؟

package-lock.json ساختار دقیق Dependencyهای نصب‌شده را ثبت می‌کند.

package.json ممکن است یک Range نسخه تعریف کند:

{
  "dependencies": {
    "express": "^5.0.0"
  }
}

اما package-lock.json نسخه دقیق و Dependencyهای غیرمستقیم را ثبت می‌کند.

طبق مستندات package-lock.json، این فایل برای توصیف دقیق درخت Dependency تولید می‌شود تا نصب‌های بعدی قابل‌تکرارتر باشند.

آیا package-lock.json را وارد Git کنیم؟

برای اپلیکیشن‌ها معمولاً بله.

مزایا:

  • نصب قابل‌پیش‌بینی‌تر
  • هماهنگی محیط اعضای تیم
  • نصب دقیق‌تر در CI
  • مشاهده تغییر Dependencyها در Pull Request
  • Debug ساده‌تر تفاوت نسخه‌ها

حذف Lock File برای حل تصادفی مشکلات Dependency همیشه راه‌حل مناسبی نیست. ابتدا علت تعارض یا نصب ناموفق را بررسی کنید.

تفاوت npm install و npm ci

npm install

npm install

ویژگی‌ها:

  • برای توسعه روزمره مناسب است.
  • می‌تواند Lock File را به‌روزرسانی کند.
  • Package جدید نصب می‌کند.
  • تغییرات package.json را مدیریت می‌کند.

npm ci

npm ci

ویژگی‌های عمومی:

  • برای CI و نصب تمیز مناسب است.
  • به Lock File نیاز دارد.
  • نصب را براساس Dependencyهای Lock‌شده انجام می‌دهد.
  • اگر package.json و Lock File هماهنگ نباشند، خطا می‌دهد.
  • پوشه node_modules را پیش از نصب تمیز بازسازی می‌کند.

قاعده عملی:

Development → npm install
CI/CD → npm ci

Semantic Versioning یا SemVer

نسخه Package معمولاً سه بخش دارد:

MAJOR.MINOR.PATCH

مثال:

2.4.7

معنای عمومی:

  • MAJOR: تغییر ناسازگار
  • MINOR: قابلیت جدید سازگار
  • PATCH: اصلاح سازگار

مثال:

1.0.0 → 1.0.1

اصلاح کوچک و سازگار.

1.0.0 → 1.1.0

قابلیت جدید سازگار.

1.0.0 → 2.0.0

تغییر ناسازگار با نسخه قبلی.

علامت ^ در نسخه npm

{
  "express": "^5.0.0"
}

به‌طور عمومی، ^ اجازه به‌روزرسانی سازگار در محدوده Major را می‌دهد:

>=5.0.0 و <6.0.0

رفتار نسخه‌های قبل از 1.0.0 محدودتر است و باید با دقت بررسی شود.

علامت ~ در نسخه npm

{
  "package-name": "~2.4.1"
}

معمولاً اجازه تغییر Patch را می‌دهد:

>=2.4.1 و <2.5.0

نسخه دقیق

{
  "package-name": "2.4.1"
}

فقط همان نسخه در package.json درخواست شده است. Lock File همچنان Dependencyهای غیرمستقیم را ثبت می‌کند.

latest به چه معنا است؟

هنگام نصب:

npm install package-name@latest

latest یک Dist Tag است، نه الزاماً مفهومی مانند «جدیدترین نسخه قابل‌تصور». Maintainer مشخص می‌کند کدام نسخه با Tag برابر با latest ارائه شود.

Package می‌تواند Tagهای دیگری نیز داشته باشد:

latest
beta
next
canary

برای Production نباید بدون بررسی، نسخه آزمایشی را جایگزین نسخه پایدار کنید.

npm Scripts چیست؟

در package.json می‌توان Commandهای پروژه را تعریف کرد:

{
  "scripts": {
    "dev": "node --watch src/server.js",
    "start": "node src/server.js",
    "test": "node --test",
    "lint": "eslint ."
  }
}

اجرا:

npm run dev
npm run lint

برای بعضی Scriptهای استاندارد می‌توان run را حذف کرد:

npm start
npm test

طبق راهنمای رسمی npm Scripts، Scriptها از طریق Shell اجرا می‌شوند و Executableهای محلی پوشه node_modules/.bin در مسیر اجرای Script در دسترس قرار می‌گیرند.

به همین دلیل برای اجرای ESLint محلی لازم نیست مسیر کامل بنویسیم:

{
  "scripts": {
    "lint": "eslint ."
  }
}

pre و post Script

npm بعضی Hookهای قبل و بعد از Script را پشتیبانی می‌کند:

{
  "scripts": {
    "pretest": "npm run lint",
    "test": "node --test",
    "posttest": "echo Tests completed"
  }
}

با اجرای:

npm test

ترتیب مفهومی:

pretest
test
posttest

Scriptها می‌توانند کد اجرا کنند؛ بنابراین Package و Scriptهای پروژه را آگاهانه بررسی کنید.

تفاوت npm و npx

npm

برای مدیریت Package و اجرای Scriptهای پروژه:

npm install
npm run build

npx

برای اجرای Binary یک Package:

npx eslint .

یا ایجاد پروژه:

npx create-vite

در نسخه‌های جدید npm، npx با سازوکار npm exec ارتباط نزدیکی دارد:

npm exec -- eslint .

برای ابزارهای تکرارشونده پروژه، نصب محلی و تعریف Script معمولاً قابل‌پیش‌بینی‌تر است:

npm install -D eslint
{
  "scripts": {
    "lint": "eslint ."
  }
}

سپس:

npm run lint

نصب محلی و Global

نصب محلی

npm install package-name

Package داخل پروژه نصب می‌شود.

نصب Global

npm install --global package-name

نسخه کوتاه:

npm install -g package-name

نصب Global بیشتر برای ابزارهای CLI عمومی استفاده می‌شود. برای Build Tool و Linter پروژه، نصب محلی معمولاً بهتر است؛ زیرا نسخه ابزار همراه پروژه ثبت می‌شود.

حذف Package

npm uninstall express

نسخه کوتاه:

npm remove express

npm ورودی مربوط را از package.json و Lock File نیز به‌روزرسانی می‌کند.

مشاهده Packageهای نصب‌شده

Dependencyهای مستقیم:

npm list --depth=0

Dependency خاص:

npm list express

علت نصب یک Package:

npm explain package-name

این دستور هنگام بررسی Dependency غیرمستقیم مفید است.

بررسی Packageهای قدیمی

npm outdated

این دستور نسخه فعلی، نسخه مورد انتظار و نسخه جدیدتر را نمایش می‌دهد.

به‌روزرسانی در محدوده مجاز package.json:

npm update

برای ارتقای Major باید Release Note و تغییرات ناسازگار را بررسی کنید.

npm audit چیست؟

npm audit

این دستور Dependencyها را با اطلاعات آسیب‌پذیری‌های شناخته‌شده بررسی می‌کند.

اصلاح خودکار سازگار در صورت امکان:

npm audit fix

از اجرای بدون بررسی گزینه‌هایی که تغییرات ناسازگار اعمال می‌کنند اجتناب کنید. پس از هر به‌روزرسانی:

  • تست‌ها را اجرا کنید.
  • Build را بررسی کنید.
  • رفتار برنامه را آزمایش کنید.
  • تغییرات Lock File را مرور کنید.

گزارش Audit همیشه به معنای قابل‌استفاده بودن مستقیم یک آسیب‌پذیری در معماری شما نیست، اما نباید بدون بررسی نادیده گرفته شود.

فایل .npmrc چیست؟

.npmrc تنظیمات npm را نگهداری می‌کند.

نمونه:

save-exact=true

یا تنظیم Registry:

registry=https://registry.npmjs.org/

فایل .npmrc می‌تواند در سطح پروژه یا کاربر وجود داشته باشد.

Token یا Credential واقعی را در .npmrc واردشده به Git قرار ندهید. در CI از Secretهای محیط اجرا استفاده کنید.

Environment Variable و فایل .env

npm به‌تنهایی فایل .env را مانند کد JavaScript بارگذاری نمی‌کند. برای برنامه Node.js می‌توان از روش Runtime یا Package مناسب استفاده کرد.

نمونه با dotenv:

npm install dotenv
import "dotenv/config";

const apiKey =
  process.env.DARVAREH_API_KEY;

فایل .env:

DARVAREH_API_KEY=YOUR_DARVAREH_API_KEY

فایل .gitignore:

.env
node_modules/

API Key نباید داخل package.json قرار گیرد.

پروژه عملی: ساخت Package برای API درواره

در این پروژه Package کوچکی می‌سازیم که در برنامه‌های Node.js قابل‌استفاده باشد.

قابلیت‌ها:

  • تنظیم API Key
  • تنظیم Base URL
  • انتخاب Model ID
  • ارسال Chat Completion
  • اعتبارسنجی پیام‌ها
  • مدیریت Timeout
  • پشتیبانی از AbortSignal
  • خطای ساختاریافته
  • تست با Test Runner داخلی Node.js
  • نصب محلی در یک پروژه نمونه
  • بررسی محتویات Package پیش از انتشار

این Package برای استفاده سمت سرور طراحی می‌شود. نباید آن را همراه API Key در کد مرورگر استفاده کرد.

ساختار پروژه

darvareh-client/
├── src/
│   ├── client.js
│   ├── errors.js
│   └── index.js
├── test/
│   └── client.test.js
├── .gitignore
├── package.json
└── README.md

مرحله اول: ایجاد Package

mkdir darvareh-client
cd darvareh-client
npm init -y

مرحله دوم: تنظیم package.json

فایل package.json:

{
  "name": "@your-scope/darvareh-client",
  "version": "0.1.0",
  "description": "A server-side JavaScript client for Darvareh AI API",
  "private": true,
  "type": "module",
  "exports": {
    ".": "./src/index.js",
    "./errors": "./src/errors.js"
  },
  "files": [
    "src",
    "README.md"
  ],
  "scripts": {
    "test": "node --test",
    "test:watch": "node --test --watch",
    "pack:check": "npm pack --dry-run"
  },
  "keywords": [
    "artificial-intelligence",
    "ai-api",
    "javascript",
    "nodejs",
    "darvareh"
  ],
  "engines": {
    "node": ">=20"
  },
  "license": "UNLICENSED"
}

در این مثال:

  • private: true از انتشار تصادفی جلوگیری می‌کند.
  • type: module استفاده از ESM را فعال می‌کند.
  • exports مسیرهای عمومی را مشخص می‌کند.
  • files فایل‌های قابل‌بسته‌بندی را محدود می‌کند.
  • scripts فرمان‌های تست و بررسی Package را تعریف می‌کند.
  • engines نسخه مورد انتظار Node.js را اعلام می‌کند.

پیش از انتشار عمومی باید نام، Scope، License، README و سیاست نسخه‌بندی را مشخص کنید و private را فقط آگاهانه تغییر دهید.

مرحله سوم: ساخت Error اختصاصی

فایل src/errors.js:

export class DarvarehApiError extends Error {
  constructor(
    message,
    {
      status = null,
      code = null,
      details = null,
      cause = undefined
    } = {}
  ) {
    super(message, {
      cause
    });

    this.name = "DarvarehApiError";
    this.status = status;
    this.code = code;
    this.details = details;
  }
}

با Error اختصاصی، برنامه مصرف‌کننده می‌تواند خطاهای API را از سایر خطاها تشخیص دهد.

مرحله چهارم: ساخت Client

فایل src/client.js:

import {
  DarvarehApiError
} from "./errors.js";

const DEFAULT_BASE_URL =
  "https://api.darvareh.ir/v1";

function normalizeBaseUrl(value) {
  return value.replace(/\/+$/, "");
}

function validateMessages(messages) {
  if (
    !Array.isArray(messages) ||
    messages.length === 0
  ) {
    throw new TypeError(
      "messages must be a non-empty array"
    );
  }

  const validRoles = new Set([
    "system",
    "user",
    "assistant"
  ]);

  for (const message of messages) {
    const isValid =
      message !== null &&
      typeof message === "object" &&
      validRoles.has(message.role) &&
      typeof message.content === "string" &&
      message.content.trim().length > 0;

    if (!isValid) {
      throw new TypeError(
        "each message must contain a valid role and content"
      );
    }
  }
}

async function parseJsonResponse(response) {
  const rawBody = await response.text();

  if (!rawBody) {
    return null;
  }

  try {
    return JSON.parse(rawBody);
  } catch (error) {
    throw new DarvarehApiError(
      "API response is not valid JSON",
      {
        status: response.status,
        cause: error
      }
    );
  }
}

function getErrorMessage(data, status) {
  const apiMessage =
    data?.error?.message ??
    data?.message ??
    data?.error;

  if (
    typeof apiMessage === "string" &&
    apiMessage.trim()
  ) {
    return apiMessage;
  }

  return `API request failed with status ${status}`;
}

export class DarvarehClient {
  #apiKey;
  #baseUrl;
  #defaultModel;
  #timeoutMs;
  #fetch;

  constructor({
    apiKey,
    baseUrl = DEFAULT_BASE_URL,
    defaultModel = null,
    timeoutMs = 60000,
    fetchImpl = globalThis.fetch
  }) {
    if (
      typeof apiKey !== "string" ||
      !apiKey.trim()
    ) {
      throw new TypeError(
        "apiKey is required"
      );
    }

    if (typeof fetchImpl !== "function") {
      throw new TypeError(
        "A fetch implementation is required"
      );
    }

    if (
      !Number.isFinite(timeoutMs) ||
      timeoutMs <= 0
    ) {
      throw new TypeError(
        "timeoutMs must be a positive number"
      );
    }

    this.#apiKey = apiKey;
    this.#baseUrl =
      normalizeBaseUrl(baseUrl);

    this.#defaultModel = defaultModel;
    this.#timeoutMs = timeoutMs;
    this.#fetch = fetchImpl;
  }

  async chat({
    messages,
    model = this.#defaultModel,
    temperature = 0.4,
    maxTokens = 1200,
    signal
  }) {
    validateMessages(messages);

    if (
      typeof model !== "string" ||
      !model.trim()
    ) {
      throw new TypeError(
        "model is required"
      );
    }

    const timeoutController =
      new AbortController();

    const timeoutId = setTimeout(() => {
      timeoutController.abort(
        new Error("Request timeout")
      );
    }, this.#timeoutMs);

    const combinedSignal =
      signal
        ? AbortSignal.any([
            signal,
            timeoutController.signal
          ])
        : timeoutController.signal;

    try {
      const response = await this.#fetch(
        `${this.#baseUrl}/chat/completions`,
        {
          method: "POST",

          headers: {
            "Authorization":
              `Bearer ${this.#apiKey}`,

            "Content-Type":
              "application/json"
          },

          body: JSON.stringify({
            model,
            messages,
            temperature,
            max_tokens: maxTokens
          }),

          signal: combinedSignal
        }
      );

      const data =
        await parseJsonResponse(response);

      if (!response.ok) {
        throw new DarvarehApiError(
          getErrorMessage(
            data,
            response.status
          ),
          {
            status: response.status,
            code:
              data?.error?.code ??
              data?.code ??
              null,
            details: data
          }
        );
      }

      const content =
        data?.choices?.[0]?.message?.content;

      if (
        typeof content !== "string" ||
        !content.trim()
      ) {
        throw new DarvarehApiError(
          "API response does not contain message content",
          {
            status: response.status,
            details: data
          }
        );
      }

      return {
        content,
        usage: data?.usage ?? null,
        model: data?.model ?? model,
        raw: data
      };
    } catch (error) {
      if (error instanceof DarvarehApiError) {
        throw error;
      }

      if (
        error.name === "AbortError" ||
        combinedSignal.aborted
      ) {
        throw new DarvarehApiError(
          "The request was cancelled or timed out",
          {
            cause: error
          }
        );
      }

      throw new DarvarehApiError(
        "Unable to connect to the API",
        {
          cause: error
        }
      );
    } finally {
      clearTimeout(timeoutId);
    }
  }
}

نکته درباره AbortSignal.any

در این نمونه از API جدیدتر AbortSignal.any استفاده شده است. به همین دلیل در engines نسخه جدیدی از Node.js اعلام کردیم.

اگر Runtime هدف شما از این قابلیت پشتیبانی نمی‌کند، می‌توانید:

  • حداقل نسخه Node.js را افزایش دهید.
  • یک تابع ترکیب Signal پیاده‌سازی کنید.
  • فقط Timeout داخلی را نگه دارید.
  • سازگاری را پیش از انتشار آزمایش کنید.

فیلد engines به‌تنهایی سازگاری را تضمین نمی‌کند؛ تست باید روی نسخه‌های اعلام‌شده اجرا شود.

مرحله پنجم: ساخت Entry Point

فایل src/index.js:

export {
  DarvarehClient
} from "./client.js";

export {
  DarvarehApiError
} from "./errors.js";

اکنون مصرف‌کننده می‌تواند بنویسد:

import {
  DarvarehClient,
  DarvarehApiError
} from "@your-scope/darvareh-client";

مرحله ششم: نوشتن تست

تست نباید درخواست واقعی ارسال کند یا هزینه API ایجاد کند. یک fetchImpl ساختگی تزریق می‌کنیم.

فایل test/client.test.js:

import test from "node:test";
import assert from "node:assert/strict";

import {
  DarvarehApiError,
  DarvarehClient
} from "../src/index.js";

test(
  "returns assistant content",
  async () => {
    const calls = [];

    const fakeFetch = async (
      url,
      options
    ) => {
      calls.push({
        url,
        options
      });

      return new Response(
        JSON.stringify({
          model: "test-model",
          choices: [
            {
              message: {
                role: "assistant",
                content: "پاسخ آزمایشی"
              }
            }
          ],
          usage: {
            prompt_tokens: 10,
            completion_tokens: 5,
            total_tokens: 15
          }
        }),
        {
          status: 200,
          headers: {
            "Content-Type":
              "application/json"
          }
        }
      );
    };

    const client = new DarvarehClient({
      apiKey: "test-api-key",
      defaultModel: "test-model",
      fetchImpl: fakeFetch
    });

    const result = await client.chat({
      messages: [
        {
          role: "user",
          content: "سلام"
        }
      ]
    });

    assert.equal(
      result.content,
      "پاسخ آزمایشی"
    );

    assert.equal(calls.length, 1);

    assert.equal(
      calls[0].url,
      "https://api.darvareh.ir/v1/chat/completions"
    );

    const body = JSON.parse(
      calls[0].options.body
    );

    assert.equal(
      body.model,
      "test-model"
    );
  }
);

test(
  "throws for invalid messages",
  async () => {
    const client = new DarvarehClient({
      apiKey: "test-api-key",
      defaultModel: "test-model"
    });

    await assert.rejects(
      () => client.chat({
        messages: []
      }),
      TypeError
    );
  }
);

test(
  "creates a structured API error",
  async () => {
    const fakeFetch = async () => {
      return new Response(
        JSON.stringify({
          error: {
            message:
              "Request was not accepted",
            code: "invalid_request"
          }
        }),
        {
          status: 400,
          headers: {
            "Content-Type":
              "application/json"
          }
        }
      );
    };

    const client = new DarvarehClient({
      apiKey: "test-api-key",
      defaultModel: "test-model",
      fetchImpl: fakeFetch
    });

    await assert.rejects(
      () => client.chat({
        messages: [
          {
            role: "user",
            content: "سلام"
          }
        ]
      }),

      (error) => {
        assert.ok(
          error instanceof DarvarehApiError
        );

        assert.equal(
          error.status,
          400
        );

        assert.equal(
          error.code,
          "invalid_request"
        );

        return true;
      }
    );
  }
);

اجرای تست:

npm test

حالت Watch:

npm run test:watch

مرحله هفتم: نوشتن README

فایل README.md:

# Darvareh JavaScript Client

یک Client سمت سرور برای اتصال برنامه‌های Node.js به API درواره.

## Requirements

- Node.js 20 یا جدیدتر

## Local installation

```bash
npm install ../darvareh-client

Usage

import {
  DarvarehClient
} from "@your-scope/darvareh-client";

const client = new DarvarehClient({
  apiKey: process.env.DARVAREH_API_KEY,
  defaultModel: process.env.DARVAREH_MODEL_ID
});

const response = await client.chat({
  messages: [
    {
      role: "user",
      content: "JavaScript چیست؟"
    }
  ]
});

console.log(response.content);

API Key را فقط در محیط امن سمت سرور نگهداری کنید.


وجود README برای Package اهمیت زیادی دارد. README باید حداقل شامل این موارد باشد:

- هدف Package
- روش نصب
- نمونه استفاده
- نسخه Runtime
- API عمومی
- مدیریت خطا
- محدودیت‌ها
- License

## مرحله هشتم: بررسی محتویات Package

قبل از انتشار یا انتقال Package:

```bash
npm run pack:check

یا:

npm pack --dry-run

این دستور نشان می‌دهد چه فایل‌هایی وارد Package خواهند شد.

مواردی که نباید وارد Package عمومی شوند:

  • .env
  • API Key
  • فایل Test غیرضروری
  • Log
  • Credential
  • فایل حجیم توسعه
  • تنظیمات خصوصی
  • Dataset داخلی
  • خروجی موقت

مرحله نهم: ساخت فایل tgz

npm pack

خروجی مشابه:

your-scope-darvareh-client-0.1.0.tgz

این فایل را می‌توان در یک پروژه دیگر نصب کرد:

npm install ../darvareh-client/your-scope-darvareh-client-0.1.0.tgz

تا زمانی که private: true فعال است، Package را عمومی منتشر نمی‌کنیم؛ اما می‌توانیم آن را محلی تست کنیم.

استفاده از Package در پروژه نمونه

پوشه جدید:

mkdir darvareh-client-demo
cd darvareh-client-demo
npm init -y

تنظیم ESM:

npm pkg set type=module

نصب dotenv:

npm install dotenv

نصب Package محلی:

npm install ../darvareh-client

فایل .env:

DARVAREH_API_KEY=YOUR_DARVAREH_API_KEY
DARVAREH_MODEL_ID=YOUR_MODEL_ID

فایل index.js:

import "dotenv/config";

import {
  DarvarehApiError,
  DarvarehClient
} from "@your-scope/darvareh-client";

const client = new DarvarehClient({
  apiKey:
    process.env.DARVAREH_API_KEY,

  defaultModel:
    process.env.DARVAREH_MODEL_ID,

  timeoutMs: 60000
});

try {
  const result = await client.chat({
    messages: [
      {
        role: "system",
        content:
          "شما یک دستیار فارسی و دقیق هستید."
      },
      {
        role: "user",
        content:
          "npm و npx چه تفاوتی دارند؟"
      }
    ]
  });

  console.log(result.content);

  if (result.usage) {
    console.log(
      "Usage:",
      result.usage
    );
  }
} catch (error) {
  if (error instanceof DarvarehApiError) {
    console.error(
      "API request failed:",
      {
        message: error.message,
        status: error.status,
        code: error.code
      }
    );

    process.exitCode = 1;
  } else {
    throw error;
  }
}

اجرا:

node index.js

برای دریافت API Key می‌توانید در درواره ثبت‌نام کنید. برای انتخاب Model ID و مشاهده اطلاعات به‌روز قیمت مدل‌ها به صفحه مدل‌های درواره مراجعه کنید.

چرا این Package را در مرورگر استفاده نمی‌کنیم؟

Package برای Node.js و محیط امن سمت سرور طراحی شده است.

این کد در React سمت مرورگر مناسب نیست:

const client = new DarvarehClient({
  apiKey: "YOUR_DARVAREH_API_KEY"
});

اگر API Key وارد Bundle مرورگر شود، کاربر می‌تواند آن را مشاهده کند.

معماری مناسب:

React یا مرورگر
    ↓
Backend شما
    ↓
Package داخلی درواره
    ↓
API درواره

ایجاد Command با npm pkg

npm می‌تواند بعضی فیلدهای package.json را بدون ویرایش دستی تغییر دهد:

npm pkg set type=module

افزودن Script:

npm pkg set scripts.test="node --test"

خواندن نام Package:

npm pkg get name

این دستورات برای Automation و Scriptهای Setup مفید هستند.

npm Workspaces چیست؟

Workspaces امکان مدیریت چند Package مرتبط را در یک Repository فراهم می‌کند.

ساختار:

ai-platform/
├── apps/
│   ├── dashboard/
│   └── api/
├── packages/
│   ├── darvareh-client/
│   └── shared-config/
├── package.json
└── package-lock.json

فایل ریشه:

{
  "name": "ai-platform",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ]
}

هر Workspace می‌تواند package.json خود را داشته باشد.

مزایا:

  • مدیریت چند پروژه در یک Repository
  • اشتراک Package داخلی
  • یک Lock File مرکزی
  • اجرای Script در Workspace مشخص
  • نصب Dependency برای Package خاص
  • توسعه هم‌زمان Frontend و Backend

اجرای Script در Workspace

npm run dev --workspace=apps/dashboard

اجرای Script در تمام Workspaces:

npm run test --workspaces

نصب Dependency در Workspace:

npm install express --workspace=apps/api

Workspaces برای پروژه‌ای شامل Frontend، Backend، SDK و Package مشترک بسیار مفید هستند.

ساخت CLI با فیلد bin

یک Package می‌تواند Command خط فرمان ارائه دهد.

فایل src/cli.js:

#!/usr/bin/env node

console.log(
  "Darvareh client is ready"
);

در package.json:

{
  "bin": {
    "darvareh-client":
      "./src/cli.js"
  }
}

پس از نصب Package، Command مربوط در دسترس قرار می‌گیرد. برای CLI واقعی باید ورودی، خروجی، کد Exit و مدیریت خطا به‌درستی طراحی شوند.

هیچ API Key را به‌صورت پیش‌فرض در Argument خط فرمان قرار ندهید؛ زیرا ممکن است در History یا فهرست Processها دیده شود. استفاده از Environment Variable مناسب‌تر است.

انتشار Package در npm

پیش از انتشار عمومی باید این موارد آماده باشند:

  • نام یکتا
  • نسخه صحیح
  • README کامل
  • License
  • فایل‌های محدودشده با files
  • تست موفق
  • Build موفق
  • عدم وجود Secret
  • حساب npm
  • سیاست انتشار
  • دسترسی مناسب Package
  • روش احراز هویت امن

ورود:

npm login

مشاهده کاربر:

npm whoami

بررسی محتویات:

npm pack --dry-run

انتشار:

npm publish

برای Scoped Package عمومی ممکن است تنظیم Access لازم باشد:

npm publish --access public

در پروژه این مقاله عمداً private: true گذاشته‌ایم تا انتشار تصادفی انجام نشود. تا زمانی که Package واقعاً برای انتشار آماده نشده، این فیلد را حذف نکنید.

افزایش نسخه Package

Patch:

npm version patch

Minor:

npm version minor

Major:

npm version major

این دستورها می‌توانند نسخه را در package.json تغییر دهند و بسته به تنظیمات، عملیات مرتبط با Git را نیز انجام دهند. قبل از اجرا وضعیت Repository و رفتار نسخه npm خود را بررسی کنید.

قاعده عمومی انتشار:

Bug Fix سازگار → Patch
Feature سازگار → Minor
Breaking Change → Major

انتخاب Package مناسب

قبل از نصب یک Package این موارد را بررسی کنید:

  • آیا واقعاً به Dependency نیاز دارید؟
  • مستندات روشن دارد؟
  • Repository و Issue Tracker مشخص است؟
  • نسخه‌های جدید منظم منتشر می‌شوند؟
  • API آن پایدار است؟
  • License برای پروژه مناسب است؟
  • تعداد Dependencyهای غیرمستقیم چقدر است؟
  • Bundle Size برای Frontend مناسب است؟
  • Type Definition دارد؟
  • با Runtime هدف سازگار است؟
  • جایگزین ساده‌تر داخلی وجود دارد؟
  • Package منسوخ نشده است؟

تعداد Download به‌تنهایی کیفیت یا تناسب Package با پروژه شما را تضمین نمی‌کند.

مدیریت Dependency در پروژه هوش مصنوعی

در پروژه‌های متصل به مدل‌های هوش مصنوعی، Dependencyها معمولاً در چند دسته قرار می‌گیرند:

دستهنمونه کاربرد
HTTP Clientارتباط با API
Validationبررسی ورودی و خروجی
Web Frameworkساخت Backend
Environmentخواندن تنظیمات
Databaseذخیره مکالمه
Queueپردازش Async
Loggingمشاهده‌پذیری
Testingتست Client و API

برای هر Dependency جدید از خود بپرسید:

آیا این قابلیت با API داخلی Runtime قابل‌پیاده‌سازی است؟
آیا هزینه نگهداری Package از ارزش آن کمتر است؟
آیا نسخه و License آن مناسب است؟
آیا در Production واقعاً استفاده می‌شود؟

در Package نمونه، برای درخواست HTTP از fetch داخلی Node.js استفاده کردیم و Dependency Runtime جدیدی اضافه نکردیم.

خطاهای رایج npm

دستور npm شناخته نمی‌شود

خطا:

npm: command not found

یا در ویندوز:

'npm' is not recognized

بررسی کنید:

  • Node.js نصب است؟
  • Terminal پس از نصب دوباره باز شده؟
  • PATH درست تنظیم شده؟
  • Version Manager فعال است؟
  • Command از Shell صحیح اجرا می‌شود؟

خطای EACCES

این خطا معمولاً به Permission هنگام نصب Global مربوط است. تغییر Permissionهای سیستمی بدون شناخت می‌تواند مشکل بیشتری ایجاد کند. استفاده از Version Manager یا تنظیم صحیح مسیر Global معمولاً روش مناسب‌تری است.

تعارض Dependency

ممکن است Packageها نسخه‌های ناسازگار Peer Dependency درخواست کنند.

راهکار:

  • متن کامل خطا را بخوانید.
  • نسخه Packageها را بررسی کنید.
  • Release Note را ببینید.
  • Dependency مستقیم و Peer را هماهنگ کنید.
  • از Force کردن نصب بدون بررسی اجتناب کنید.

package.json نامعتبر

بررسی JSON:

  • Double Quote
  • نبود Comment
  • نبود Comma اضافی
  • بسته‌شدن {} و []

Script پیدا نمی‌شود

خطا:

Missing script: "dev"

فهرست Scriptها:

npm run

فایل package.json را بررسی کنید:

{
  "scripts": {
    "dev": "node --watch index.js"
  }
}

Package نصب است اما Import نمی‌شود

بررسی کنید:

  • Package در dependencies وجود دارد؟
  • نام Import صحیح است؟
  • ESM یا CommonJS درست تنظیم شده؟
  • فیلد exports مسیر را اجازه می‌دهد؟
  • نسخه Node.js سازگار است؟
  • Package فقط Type است یا Runtime Code دارد؟

تغییر Package اعمال نمی‌شود

در Package محلی ممکن است نیاز باشد:

  • Package دوباره نصب شود.
  • نسخه افزایش یابد.
  • Tarball جدید ساخته شود.
  • Cache ابزار Build پاک شود.
  • Dev Server Restart شود.

آیا پاک‌کردن node_modules راه‌حل خوبی است؟

گاهی بازسازی نصب مشکل محیطی را حل می‌کند:

rm -rf node_modules
npm ci

در PowerShell:

Remove-Item node_modules -Recurse -Force
npm ci

اما پیش از حذف بررسی کنید:

  • تغییر محلی داخل node_modules ندارید؟
  • Lock File معتبر است؟
  • package.json با Lock File هماهنگ است؟
  • مشکل از نسخه Node.js نیست؟
  • خطای Registry یا شبکه وجود ندارد؟

به‌صورت عادی نباید فایل‌های داخل node_modules را مستقیم ویرایش کنید.

بهترین روش‌های استفاده از npm

  • package-lock.json را برای اپلیکیشن وارد Git کنید.
  • در CI از npm ci استفاده کنید.
  • node_modules را وارد Git نکنید.
  • Scriptهای اصلی را در package.json ثبت کنید.
  • برای ابزار پروژه از نصب محلی استفاده کنید.
  • Dependency غیرضروری اضافه نکنید.
  • Release Note نسخه‌های Major را بخوانید.
  • Packageهای قدیمی را دوره‌ای بررسی کنید.
  • تست را پس از Update اجرا کنید.
  • .env را وارد Git نکنید.
  • Token را در فایل عمومی .npmrc نگذارید.
  • پیش از Publish از npm pack --dry-run استفاده کنید.
  • Package داخلی را با private: true محافظت کنید.
  • Runtime موردنیاز را در engines اعلام کنید.
  • API عمومی Package را با exports محدود کنید.
  • نسخه Package را براساس SemVer تغییر دهید.
  • API Key در Package Hardcode نکنید.

چک‌لیست package.json

  • name صحیح و معتبر است.
  • version از SemVer پیروی می‌کند.
  • private برای اپلیکیشن تنظیم شده است.
  • type با ESM یا CommonJS هماهنگ است.
  • scripts قابل‌اجرا هستند.
  • Dependencyهای Runtime درست دسته‌بندی شده‌اند.
  • ابزارهای توسعه در devDependencies هستند.
  • exports فقط مسیرهای عمومی را باز می‌کند.
  • files محتویات Package را محدود می‌کند.
  • engines Runtime موردنیاز را اعلام می‌کند.
  • License مشخص است.
  • Secret در فایل وجود ندارد.
  • JSON معتبر است.

نقشه راه یادگیری npm

مرحله اول: دستورات اصلی

npm init
npm install
npm uninstall
npm run
npm list

مرحله دوم: فایل‌های پروژه

package.json
package-lock.json
node_modules
.npmrc
.gitignore

مرحله سوم: مدیریت نسخه

Semantic Versioning
Version Range
Dist Tag
npm outdated
npm update

مرحله چهارم: Workflow تیمی

npm ci
Scripts
Testing
Lint
Build
CI/CD

مرحله پنجم: ساخت Package

exports
files
engines
README
npm pack
npm publish

مرحله ششم: پروژه بزرگ

Workspaces
Monorepo
Package داخلی
Shared Config
Versioning
Release Process

سؤال‌های متداول

npm چیست؟

npm ابزار مدیریت Packageهای JavaScript و Node.js است و شامل CLI، Registry و وب‌سایت جست‌وجوی Packageها می‌شود.

آیا npm همراه Node.js نصب می‌شود؟

در بیشتر روش‌های نصب Node.js، npm نیز نصب می‌شود. با دستور npm --version می‌توانید آن را بررسی کنید.

npm install چه کاری انجام می‌دهد؟

این دستور Dependencyها را نصب می‌کند، پوشه node_modules را می‌سازد و در صورت نیاز package.json و package-lock.json را به‌روزرسانی می‌کند.

package.json چیست؟

فایل Metadata و تنظیمات پروژه npm است و اطلاعاتی مانند نام، نسخه، Scriptها و Dependencyها را نگهداری می‌کند.

package-lock.json چیست؟

این فایل نسخه دقیق Dependencyهای نصب‌شده و ساختار درخت وابستگی را ثبت می‌کند تا نصب قابل‌تکرارتر باشد.

node_modules چیست؟

پوشه‌ای است که Packageهای نصب‌شده پروژه و Dependencyهای آن‌ها را نگهداری می‌کند.

آیا node_modules را در GitHub قرار دهیم؟

معمولاً خیر. package.json و package-lock.json را ثبت کنید و node_modules را در .gitignore قرار دهید.

تفاوت npm install و npm ci چیست؟

npm install برای توسعه و تغییر Dependencyها مناسب است. npm ci برای نصب تمیز و قابل‌تکرار براساس Lock File در CI/CD استفاده می‌شود.

تفاوت npm و npx چیست؟

npm برای نصب و مدیریت Package و اجرای Scriptها است. npx یا npm exec برای اجرای Binary یک Package استفاده می‌شود.

تفاوت dependencies و devDependencies چیست؟

dependencies برای Packageهای موردنیاز Runtime است. devDependencies برای ابزارهای توسعه، تست، Lint و Build استفاده می‌شود.

peerDependencies چیست؟

این فیلد اعلام می‌کند Package مصرف‌کننده باید نسخه سازگاری از Dependency میزبان، مانند React، داشته باشد.

علامت ^ در package.json چیست؟

به‌طور عمومی اجازه نصب نسخه‌های سازگار جدیدتر در محدوده Major را می‌دهد. رفتار نسخه‌های قبل از 1.0.0 محدودتر است.

آیا package-lock.json را حذف کنیم؟

حذف آن نباید اولین راه‌حل مشکلات نصب باشد. ابتدا تعارض Dependency، نسخه Node.js و هماهنگی package.json را بررسی کنید.

npm audit چیست؟

دستور بررسی Dependencyها در برابر اطلاعات آسیب‌پذیری‌های شناخته‌شده است. نتیجه باید همراه با معماری واقعی پروژه بررسی شود.

npm run dev چیست؟

dev یک Script تعریف‌شده توسط پروژه است. npm به‌صورت ذاتی نمی‌داند dev چه کاری انجام دهد؛ Command آن در package.json قرار دارد.

آیا می‌توان Package خصوصی ساخت؟

بله. می‌توان Package را فقط داخل Repository، Workspace، Registry خصوصی یا سازمان استفاده کرد. برای جلوگیری از انتشار تصادفی از private: true استفاده کنید.

چگونه یک Package npm بسازیم؟

پروژه را با npm init ایجاد کنید، Entry Point و exports را تعریف کنید، تست و README بنویسید و با npm pack --dry-run محتویات بسته را بررسی کنید.

آیا API Key را می‌توان داخل Package قرار داد؟

خیر. Package باید API Key را در Runtime از برنامه مصرف‌کننده دریافت کند. کلید واقعی نباید Hardcode یا منتشر شود.

آیا Client ساخته‌شده در این مقاله برای React مناسب است؟

این Client برای محیط امن سمت سرور طراحی شده است. استفاده از آن همراه کلید API در مرورگر باعث افشای کلید می‌شود. React باید به Backend برنامه متصل شود.

جمع‌بندی

npm یکی از اجزای اصلی اکوسیستم JavaScript است. این ابزار فقط Package نصب نمی‌کند؛ بلکه ساختار پروژه، نسخه Dependencyها، Scriptها، Lock File، Workspaces و فرایند بسته‌بندی را مدیریت می‌کند.

مهم‌ترین مفاهیمی که باید یاد بگیرید عبارت‌اند از:

  • Package و Module
  • npm CLI و Registry
  • package.json
  • package-lock.json
  • node_modules
  • dependencies
  • devDependencies
  • Semantic Versioning
  • npm Scripts
  • تفاوت npm و npx
  • تفاوت npm install و npm ci
  • Workspaces
  • ساخت و بسته‌بندی Package

در پروژه عملی این مقاله یک Client سمت سرور برای API درواره ساختیم. Package دارای Entry Point مشخص، Error اختصاصی، Timeout، اعتبارسنجی پیام، تست بدون درخواست واقعی و Script بررسی محتویات بسته بود.

این الگو را می‌توان برای ساخت SDK داخلی، کتابخانه مشترک سازمانی، ابزار CLI یا Package قابل‌استفاده در چند Backend توسعه داد.

برای دریافت API Key و شروع استفاده از مدل‌های هوش مصنوعی می‌توانید در درواره ثبت‌نام کنید. برای انتخاب Model ID، بررسی قابلیت مدل‌ها و مشاهده اطلاعات به‌روز قیمت نیز صفحه مدل‌های درواره را ببینید.

منابع تکمیلی

مقالات مرتبط

برای مطالعه شرایط استفاده و محدودیت‌های مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.

Read more

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی با ترکیب گردش‌کارهای خودکار و مدل‌های هوش مصنوعی، پردازش متن، دسته‌بندی، استخراج اطلاعات و تصمیم‌های پیشنهادی را خودکار می‌کند. در این راهنما، معماری و ساخت نمونه عملی آن با API درواره را می‌آموزید.

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce شیوه‌ای جدید برای خرید اینترنتی است که در آن ایجنت هوش مصنوعی می‌تواند نیاز کاربر را بفهمد، محصولات را جست‌وجو و مقایسه کند و فرایند خرید را پیش ببرد. در این راهنما با معماری، UCP، ACP و پیاده‌سازی آن با API درواره آشنا می‌شوید.