模块、导入导出与 npm 生态
专栏:TypeScript 与 Node 地基 · 第 3 / 13 篇:::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' 里的包名,按以下顺序解析:
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/session 和 packages/core/tools 就这样互相以 @deepseek-ai/dsh-session 的名义引用——源码目录结构 = 发布后的依赖图。读 monorepo 的套路:
- 读根
package.json的 scripts(构建/测试入口); - 读
pnpm-workspace.yaml知道包在哪; - 从你要读的包的
package.json看dependencies——它只依赖谁,就只需要读谁。
这也是第 5 篇(new-api 专栏)Go workspace 的镜像概念——两种语言,同一种组织智慧。
常见踩坑
- 忘了写文件扩展名——ESM 要求相对导入带
.ts/.js后缀(dsh 用显式.ts后缀 + tsx 运行器); - 循环导入:A 导入 B、B 又导入 A——类型可以循环(
import type擦除),值不行;读到”两个文件互相 import 值”要警惕; - CommonJS 的
require——旧生态的模块系统,module.exports对应export default;读老项目会遇到,新项目直接用 ESM。
随堂练习(带验收标准)
- 建两个文件:
types.ts导出一个 interface,main.ts用import type导入并使用。验收:编译产物里搜不到 interface 的痕迹; - 打开 dsh 仓库的
packages/core/session/package.json,找出它的名字、入口与依赖。验收:能顺着依赖找到它引用的下一个包; - 在
pnpm-workspace.yaml里确认packages/*/*的含义(两级通配对应core/session这种分组结构)。