夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

    • Git使用手册
    • Markdown使用教程
    • npm常用命令
    • yarn基本命令
    • npm packageJson属性详解
    • yaml语言教程
    • Stylus预处理语言
    • Less预处理语言
    • Sass预处理语言
    • PWA运用
    • 富文本编辑器Ueditor
    • 发布npm
    • 构建一个TS的npm包
      • 初始化
      • Formatting & Linting
      • 移除不必要文件
      • Jest Testing
      • 写一个测试用例
      • scripts in NPM
      • 终极版 package.json
      • 提交并推送到 Git
      • 发布
      • 创建一个新版本
    • tsup打包工具
    • leaflet地图框架
    • pdfjs-dist使用
    • xlsx插件使用
    • changesets
    • release-it
    • mathjs
  • GitHub技巧

  • 博客搭建

  • Ajax

  • Vite

  • Vitest

  • Nuxt

  • UI库文章

  • Docker

  • 技术
  • 技术文档
夜猫子
2023-07-17
目录

构建一个TS的npm包

# 初始化

1.NPM 初始化包,后续我们会修改生成的 package.json。

npm init -y
1

2.下载 TypeScript。

npm i -D typescript
1

下载完后,在根目录下多了 node_modules 文件夹和 package-lock.json 文件。

为了编译 TypeScript,我们需要一个配置文件,在根目录下新建 tsconfig.json,内容如下。

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./lib",
    "strict": true,
    "lib": ["es6"]
  },
  "include": ["src"],
  "exclude": ["node_modules", "**/__tests__/*"]
}
1
2
3
4
5
6
7
8
9
10
11
12

下面解释下配置文件字段:注意 ES6 = ES2015

  • target:编译之后生成的 JavaScript 文件需要遵循的标准,可选值:"ES3"(默认),"ES5","ES6"/"ES2015","ES2016","ES2017"或"ESNext"。我们选择了 es5 为了使包具有更好的浏览器兼容性。
  • module:指定生成哪个模块系统代码,默认值:target === "ES3" or "ES5" ? "CommonJS" : "ES6"。
  • declaration:是否生成对应的声明文件,默认值:false。在构建包时,应该设置为 true,这样 TypeScript 会将生成的声明文件和对应编译后的 JavaScript 代码一起导出,以便包可以在 TypeScript 和 JavaScript 项目中同时使用。本项目中生成的声明文件是 /lib/index.d.ts。
  • outDir:指定输出目录。编译后的 JavaScript 代码会在与 tsconfig.json 同级的 lib 文件夹中。
  • strict:是否启用所有严格类型检查选项,默认值:false。
  • lib:编译需要的库文件,例如你指定的 target 是 ES5,但是在代码中使用了 ES6 特性,就需要在 lib 中加上 ES6。默认值:如果 lib 没有指定默认注入的库的列表,默认注入的库为:
    • target ES5:DOM,ES5,ScriptHost。
    • target ES6:DOM,ES6,DOM.Iterable,ScriptHost。
  • include:指定要编译的目录。
  • exclude:指定不编译的目录。node_modules 和 __tests__ 只是在开发阶段使用,构建阶段无需编译。

更多的编译选项可参考 www.typescriptlang.org/docs/handbo… (opens new window)

3.创建 src 文件夹,在其下新建一个 index.ts,内容如下:

export const Greeter = (name: string) => `Hello ${name}`;
1

4.在 package.json 中添加 build script。

"build": "tsc"
1

在控制台运行 npm run build,你会看到生成了一个新的 lib 文件夹,里面是编译后的 js 代码和声明文件。

除了 package-lock.json 以外, 我们一般都不希望提交自动生成的文件到 Git 上去,因为只要改变了源文件,每次 build 的时候它们都不同,就会造成很多冲突,所以我们把 lib 文件夹放到 .gitignore 中。

node_modules
/lib
1
2

# Formatting & Linting

1.下载 prettier tslint tslint-config-prettier。和 TypeScript 一样,它们只是在包开发阶段所需的工具,所以是 devDependencies。

npm i -D prettier tslint tslint-config-prettier
1

一个好的包应该包括严格的代码规范,尤其是有其他协作者共同开发时。tslint-config-prettier 能防止 TSLint 和 Prettier 格式化规则的冲突。

2.在根目录下,新建 tslint.json,添加如下内容:

{
  "extends": ["tslint:recommended", "tslint-config-prettier"]
}
1
2
3

3.在根目录下,新建 .prettierrc,添加如下内容:

{
  "printWidth": 120,
  "trailingComma": "all",
  "singleQuote": true,
  "endOfLine: 'lf',
}
1
2
3
4
5
6

4.最后,在 package.json 中添加 lint 和 format script。

"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
"lint": "tslint -p tsconfig.json"
1
2

在控制台运行 npm run lint / npm run format

npm run lint
npm run format
1
2

# 移除不必要文件

在 .gitignore 中,我们添加 /lib 是因为不想 Git 远程仓库中有编译后的文件,但对于要发布的包则恰恰相反,我们不要源代码,只需要编译后的文件!有两种方式可以实现:

  • 黑名单:新建一个 xxxxxxxxxx .npmignore 文件,在其中添加不要的文件(夹)。

    src
    tsconfig.json
    tslint.json
    .prettierrc
    
    1
    2
    3
    4

    但是,这并不是一个好的实践,因为根目录下每次新增加一个文件(夹)都需要添加到 .npmignore 中,于是有了下面这种方式。

  • 白名单:在 package.json 中设置一个要发布的文件(夹)白名单

    "files": ["lib/**/*"]
    
    1

    就是这么的简单!只有 lib 文件夹会出现在发布的包里(README.md 和 package.json 会被默认添加)。更多关于黑名单 VS 白名单的内容可以参考 blog.npmjs.org/post/165769… (opens new window)

# Jest Testing

一个好的包应该要包括单元测试。接下来,我们添加 Jest —— Facebook 开发的一个非常棒的测试框架。

  • 因为我们是针对 ts 源文件编写测试用例,所以除了 jest 还需要 ts-jest @types/jest,它们只是在开发阶段需要,所以添加到 devDependencies。

    npm i -D jest ts-jest @types/jest
    
    1
  • 配置 Jest。有两种方式,在 package.json 添加 "jest" 字段 或者 新建一个单独的配置文件。我们选择后者,因为前者配置内容会被添加到发布的包中而后者不会。新建 jestconfig.json,添加如下内容:

    {
      "transform": {
        "^.+\\.(t|j)sx?$": "ts-jest"
      },
      "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
      "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"]
    }
    
    1
    2
    3
    4
    5
    6
    7
  • 移除 package.json 中的 "test" script,添加一个新的 test script。

    "test": "jest --config jestconfig.json"
    
    1

# 写一个测试用例

是时候写一个测试用例了。在 src 目录下,新建一个 __tests__ 文件夹,在其中新建一个测试文件,文件名必须以 test.ts 结尾,例如:Greeter.test.ts。

import { Greeter } from '../index';
test('My Greeter', () => {
  expect(Greeter('Carl')).toBe('Hello Carl');
});
1
2
3
4

这个测试用例验证了当输入 'Carl' 的时候,Greeter 方法是否返回 'Hello Carl'。 接下来我们运行一下

npm run test
1

# scripts in NPM

一个好的包应该尽可能自动化。接下来,我们来看看 NPM 中其他的 scripts:prepare,prepublishOnly,perversion,version,postversion。

  • prepare:会在打包和发布包之前以及本地 npm install (不带任何参数)时运行。

    "prepare": "npm run build"
    
    1
  • prepublishOnly:在 prepare script 之前运行,并且仅在 npm publish 运行。在这里,我们可以运行 npm run test & npm run lint 以确保我们不会发布错误的不规范的代码。

    "prepublishOnly": "npm run test && npm run lint"
    
    1
  • preversion:在发布新版本包之前运行,为了更加确保新版本包的代码规范,我们可以在此运行 npm run lint。

    "preversion": "npm run lint"
    
    1
  • version:在发布新版本包之后运行。如果您的包有关联远程 Git 仓库,像我们的情况一样,每次发布新版本时都会生成一个提交和一个新的版本标记,那么就可以在此添加规范代码的命令。又因为 version script 在 git commit 之前运行,所以还可以在此添加 git add。

    "version": "npm run format && git add -A src"
    
    1
  • postversion:在发布新版本包之后运行,在 git commit之后运行,所以非常适合推送。

    "postversion": "git push && git push --tags"
    
    1

# 终极版 package.json

{
  "name": "irene-awesome-greeter",
  "version": "1.0.0",
  "description": "A nice greeter", // 
  "main": "lib/index.js", // 
  "types": "lib/index.d.ts", // 
  "scripts": {
    "test": "jest --config jestconfig.json",
    "build": "tsc",
    "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
    "lint": "tslint -p tsconfig.json",
    "prepare": "npm run build",
    "prepublishOnly": "npm run test && npm run lint",
    "preversion": "npm run lint",
    "version": "npm run format && git add -A src",
    "postversion": "git push && git push --tags"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/irenetang1993/irene-awesome-greeter.git"
  },
  "keywords": ["Hello", "Greeter"], // 
  "author": "Irene Tang", // 
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/irenetang1993/irene-awesome-greeter/issues"
  },
  "homepage": "https://github.com/irenetang1993/irene-awesome-greeter#readme",
  "devDependencies": {
    "@types/jest": "^24.0.15",
    "jest": "^24.8.0",
    "prettier": "^1.18.2",
    "ts-jest": "^24.0.2",
    "tslint": "^5.18.0",
    "tslint-config-prettier": "^1.18.0",
    "typescript": "^3.5.2"
  },
  "files": [
    "lib/**/*"
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

我们完善了 description,author,keywords 信息,修改了 main,新增了 types。 main 字段非常重要,因为指明了模块的入口。types 字段指明了声明文件的入口。

# 提交并推送到 Git

git add -A && git commit -m "Setup Package"
git push
1
2

# 发布

npm publish
1

# 创建一个新版本

执行如下命令会创建一个新版本, preversion,version,postversion scripts 会被执行:创建一个新的 tag 并且推送到我们的远程仓库。

npm version patch
1

我们再发布一次:

npm publish
1

现在,我们的包就有了一个 1.0.1 的版本了

编辑 (opens new window)
上次更新: 2023/9/12 18:20:43
发布npm
tsup打包工具

← 发布npm tsup打包工具→

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式