模块、导入导出与 npm 生态

专栏:TypeScript 与 Node 地基 · 第 3 / 13 篇
TypeScriptNode模块

:::info 学习目标 完成本篇后你能够:读懂 ESM 的 import/export 各种写法;解释 package.json 的关键字段;理解 monorepo 与 pnpm workspace 的组织方式。 前置:第 1 篇完成。预计时长:45 分钟。 :::

现代 JS/TS 有两个世界:浏览器Node。本专栏只关心 Node 侧,模块标准是 ESM(ES Modules)——dsh 就是纯 ESM 项目。

export:把东西”公开”出去

// logger.ts
export function log(msg: string) { ... }        // 具名导出:可多个
export const VERSION = '1.0'

export default class Loader { ... }             // 默认导出:每个文件最多一个

import:三种常用形态

import Loader from './loader'                   // ① 默认导入
import { log, VERSION } from './logger'         // ② 具名导入(名字必须对得上)
import type { ToolDefinition } from './types'   // ③ 只导入类型(编译后擦除)

import * as utils from './utils'                // 整体导入为命名空间
export { log } from './logger'                  // 转发(再导出)

读 dsh 源码时最常见的是 ② 和 ③。import type 是纯类型导入——它保证编译后不留任何运行时代码,库作者用它暴露”只有类型”的包(如 dsh 的类型包)。

包的导入路径从哪来

import { defineTool } from '@deepseek-ai/dsh-tools' 里的包名,按以下顺序解析:

图表(ts-modules-npm.md)

package.json 的关键字段(读任何项目先看它):

字段含义
name / version包名与版本
type: "module"该包是 ESM(否则是旧的 CommonJS)
main / exports入口文件;exports 更现代,可按条件(node/browser)给不同入口
dependencies / devDependencies运行时依赖 / 开发依赖
scripts可执行的命令(pnpm build = 运行 build 脚本)
engines要求的 Node 版本

monorepo 与 pnpm workspace

dsh 的仓库是 monorepo:一个 git 仓库里装着 50+ 个包。pnpm-workspace.yaml 声明哪些目录是包:

# pnpm-workspace.yaml(dsh 的简化版)
packages:
  - vendor/*
  - packages/*/*
  - apps/*

packages/core/sessionpackages/core/tools 就这样互相以 @deepseek-ai/dsh-session 的名义引用——源码目录结构 = 发布后的依赖图。读 monorepo 的套路:

  1. 读根 package.json 的 scripts(构建/测试入口);
  2. pnpm-workspace.yaml 知道包在哪;
  3. 从你要读的包的 package.jsondependencies——它只依赖谁,就只需要读谁。

这也是第 5 篇(new-api 专栏)Go workspace 的镜像概念——两种语言,同一种组织智慧。

常见踩坑

  1. 忘了写文件扩展名——ESM 要求相对导入带 .ts/.js 后缀(dsh 用显式 .ts 后缀 + tsx 运行器);
  2. 循环导入:A 导入 B、B 又导入 A——类型可以循环(import type 擦除),值不行;读到”两个文件互相 import 值”要警惕;
  3. CommonJS 的 require——旧生态的模块系统,module.exports 对应 export default;读老项目会遇到,新项目直接用 ESM。

随堂练习(带验收标准)

  1. 建两个文件:types.ts 导出一个 interface,main.tsimport type 导入并使用。验收:编译产物里搜不到 interface 的痕迹;
  2. 打开 dsh 仓库的 packages/core/session/package.json,找出它的名字、入口与依赖。验收:能顺着依赖找到它引用的下一个包;
  3. pnpm-workspace.yaml 里确认 packages/*/* 的含义(两级通配对应 core/session 这种分组结构)。

← 返回文章列表