Backend Typescript 1.0.0 Help

Импорт, экспорт. Пакеты

Зачем нужны import/export и npm

В экосистеме Node.js и TypeScript модули позволяют разбивать код на изолированные части и переиспользовать их. npm — стандартный менеджер пакетов, который устанавливает внешние библиотеки, управляет зависимостями и публикует ваши собственные пакеты.

  • import/export — интерфейс модульности в ES-модулях (ESM).

  • require/module.exports — интерфейс модульности в CommonJS (CJS).

  • index.ts — «баррель» (barrel), агрегирующий экспорт из нескольких файлов.

  • npm — установка, обновление, публикация пакетов и управление версиями.

Базовая настройка ESM/TS

Чтобы import/export работали предсказуемо, согласуйте настройки package.json и tsconfig.json.

{ "name": "my-app", "type": "module", "scripts": { "build": "tsc -p tsconfig.json", "start": "node dist/main.js" }, "devDependencies": { "typescript": "^5.6.0" } }
{ "compilerOptions": { "target": "ES2022", "module": "ES2022", "moduleResolution": "bundler", "outDir": "dist", "rootDir": "src", "strict": true, "esModuleInterop": true, "skipLibCheck": true }, "include": [ "src" ] }

Экспорт и импорт в TypeScript (ESM)

Именованный экспорт и импорт

// src/math/add.ts export function add(a: number, b: number): number { return a + b; } // src/main.ts // в ESM относительные пути должны включать расширение .js после компиляции console.log(add(2, 3)); // 5

Экспорт по умолчанию (default)

// src/utils/logger.ts export default function log(message: string): void { console.log(message); // демонстрация вывода } // src/main.ts import log from "./utils/logger.js"; log("Hello");

Переэкспорт (re-export) и index.ts (barrel)

index.ts собирает и переэкспортирует сущности из подпакетов, упрощая импорт в потребителях.

// src/math/index.ts export * from "./add.js"; export * from "./mul.js"; // src/main.ts import {add, mul} from "./math"; // или короче: import {add, mul} from "./math";

CommonJS кратко (для легаси)

// add.cjs function add(a, b) { return a + b; } module.exports = {add}; // main.cjs const {add} = require("./add.cjs"); console.log(add(2, 3)); // 5

Работа с пакетами (npm)

Инициализация проекта и базовые команды

npm init -y npm install lodash # зависимость для runtime npm install -D typescript # dev-зависимость npx tsc --init # создать tsconfig.json
  • dependencies — то, что нужно в рантайме.

  • devDependencies — инструменты разработки.

  • peerDependencies — ожидаемые версии пакетов у потребителя.

Семантическое версионирование и диапазоны

SemVer: MAJOR.MINOR.PATCH.

  • ^1.2.3 — обновляет MINOR и PATCH (1.x.x).

  • ~1.2.3 — обновляет только PATCH (1.2.x).

  • Точный пин: 1.2.3.

Установка внешних модулей и импорт

После установки вы импортируете пакет по имени:

import _ from "lodash"; console.log(_.capitalize("hello")); // Hello

Структура node_modules и lock-файлы

node_modules хранит дерево зависимостей. package-lock.json фиксирует точные версии.

Рабочие области (workspaces) кратко

Монорепозитории с несколькими пакетами:

{ "name": "my-monorepo", "private": true, "workspaces": [ "packages\*" ] }

Импорт модулей: относительные пути, алиасы, типы

Относительные и абсолютные пути

import {add} from "../math/add.js"; // относительный импорт import {parse} from "node:path"; // встроенный модуль Node.js import express from "express"; // внешний пакет

Пути-алиасы в TypeScript

Алиасы уменьшают "../../../" и делают импорты стабильнее.

{ "compilerOptions": { "baseUrl": "./src", "paths": { "@core/*": [ "core/*" ], "@features/*": [ "features/*" ] } } }

Типы при импорте (type-only imports)

import type {Request, Response} from "express"; export function handler(req: Request, res: Response) { res.send("ok"); }

Реализация собственного модуля (пакета)

Структура и экспорты

Минимальный пакет на TS с ESM и типами:

my-lib/ src/ index.ts sum.ts package.json tsconfig.json README.md LICENSE .npmignore
// src/sum.ts export function sum(a: number, b: number): number { return a + b; } // src/index.ts (barrel) export * from "./sum.js";
{ "name": "@scope/my-lib", "version": "1.0.0", "type": "module", "main": "./dist/index.cjs", // для CJS-потребителей (опционально) "module": "./dist/index.js", // для ESM-бандлеров (исторически) "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "require": "./dist/index.cjs" } }, "types": "./dist/index.d.ts", "sideEffects": false, "files": [ "dist" ], "scripts": { "build": "tsc -p tsconfig.json && tsup src/index.ts --format cjs,esm --dts", "prepublishOnly": "npm run build" }, "devDependencies": { "typescript": "^5.6.0", "tsup": "^8.0.0" } }

Локальная проверка пакета

# сборка npm run build # локальная ссылка npm link # в другом проекте: npm link @scope/my-lib # альтернатива без link: npm pack # создаст архив .tgz npm install ./@scope-my-lib-1.0.0.tgz

Публикация пакета в npm

  • Добавьте README, LICENSE, корректные поля name, version, exports, types, files.

  • Проверьте, что приватные файлы не попадут в публикацию: настройте .npmignore или поле files.

  • npm login, затем npm publish (для scoped пакетов по умолчанию — как приватные; для публичной публикации используйте npm publish --access public).

  • Поддерживайте SemVer и ченджлог.

Лучшие практики и подводные камни

  • Единый стиль модулей: выбирайте ESM или CJS в проекте. Смешение — источник ошибок.

  • Явные публичные API: в index.ts экспортируйте только то, что обещаете пользователю.

  • Минимум побочных эффектов: не выполняйте код на верхнем уровне модуля, который что-то мутирует при импорте.

  • Жёсткие версии в проде: фиксируйте версии ключевых зависимостей и используйте npm ci.

  • Типы — часть контракта: актуальные .d.ts повышают DX и уменьшают баги у потребителей.

  • Проверка на циклы: используйте анализаторы (madge и др.) для выявления циклических импортов.

Короткие рецепты

Совместимость ESM & CJS для потребителей

// src/index.ts export function hello(name: string) { return `Hello, ${name}!`; }
{ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "require": "./dist/index.cjs" } } }

Теперь потребители могут делать и import { hello } from "@scope/my-lib", и const { hello } = require("@scope/my-lib").

Tree-shaking и sideEffects

Если модуль не имеет побочных эффектов при импорте, укажите "sideEffects": false в package.json.

Last modified: 01 October 2025