# TypeScript 项目使用 npm 模块

URL: https://caijiao.org/typescript/typescript-tutorial/npm
Source: docs/typescript/typescript-tutorial/npm.md
Description: 菜鸟教程官网提供HTML、CSS、JavaScript、Python等编程教程，覆盖开发问题库、Reference速查、AI Coding、SEO建站和在线工具，帮助零基础与开发者系统学习并解决实际开发问题。

## 简介

npm 模块都是 JavaScript 代码。即使模块是用 TypeScript 写的，还是必须编译成 JavaScript 再发布，保证模块可以在没有 TypeScript 的环境运行。

问题就来了，TypeScript 项目开发时，加载外部 npm 模块，如果拿不到该模块的类型信息，就会导致无法开发。所以，必须有一个方法，可以拿到模块的类型信息。

有些 npm 模块本身可能包含`.d.ts`文件甚至完整的 TypeScript 代码。它的`package.json`文件里面有一个`types`字段，指向一个`.d.ts`文件，这就是它的类型声明文件。

```javascript
{
 "name": "left-pad",
 "version": "1.3.0",
 "description": "String left pad",
 "main": "index.js",
 "types": "index.d.ts",
 // ...
}
```

如果某个模块没有`.d.ts`文件，TypeScript 官方和社区就自发为常用模块添加类型描述，可以去[官方网站](https://www.typescriptlang.org/dt/search)搜索，然后安装网站给出的 npm 类型模块，通常是`@types/[模块名]`。

```bash
$ npm install --save lodash
$ npm install --save @types/lodash
```

lodash 的类型描述就是`@types/lodash`的文件`index.d.ts`。

## TS 模块转 npm 模块

TS 代码放在`ts`子目录，编译出来的 CommonJS 代码放在`dist`子目录。

## 如何写 TypeScript 模块

首先，创建模块目录，然后在该目录里面新建一个`tsconfig.json`。

```json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2015",
    "declaration": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"]
}
```

- `"declaration": true`：生成 .d.ts 文件，方便其他使用 TypeScript 的开发者加载你的库。
- `"module": "commonjs"`：编译后的模块格式为`commonjs`，表示该模块供 Node.js 使用。如果供浏览器使用，则要写成`"module": "esnext"`。
- `"target": "es2015"`：生成的 JavaScript 代码版本为 ES2015，需要 Node.js 8 以上版本。
- `"outDir": "./dist"`：编译后的文件放在`./dist`目录。
- `include`：指定需要编译的文件。

然后，使用 TypeScript 编写仓库代码。可以在`src`子目录里面，编写一个入口文件`index.ts`。

最后，编写`package.json`。

```typescript
{
  "name": "hwrld",
  "version": "1.0.0",
  "description": "Can log \"hello world\" and \"goodbye world\" to the console!",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "/dist"
  ]
}
```

里面的`"types": "dist/index.d.ts"`字段指定类型声明文件，否则使用这个库的 TypeScript 开发者找不到类型声明文件。`files`属性指定打包进入 npm 模块的文件。

然后，就是编译和发布。

```bash
$ tsc
$ npm publish
```

## 参考链接

- [How to Write a TypeScript Library](https://www.tsmean.com/articles/how-to-write-a-typescript-library/), by tsmean
