七天开发一个js工具库二:让示例使用自己的库

本文属于原创文章,转载请注明–来自桃源小盼的博客

定义工具库

定义一个js库,要在package.json中设置name、main、version。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 在根目录下生成package.json
npm init -y

// package.json
{
"name": "doraemon",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
},
"keywords": ["util"],
"author": "page",
"license": "ISC"
}

在示例项目引用

可能有些人知道使用npm link,就可以在示例项目引用我们的包。不过既然我们用了pnpm,可以使用pnpm提供的工作空间workspace功能。

通过工作空间workspace(等于monorepo),我们也可以在examples目录中引入本地的包,还能限制在根目录范围内,不会影响到其他目录,比link方式要好。

新增工作空间配置文件,在根目录新建pnpm-workspace.yaml。默认情况下,包含了所有子目录和根目录的package,所以packages什么也不加。

1
2
// pnpm-workspace.yaml
packages:

在examples中引用,这里引用的方式有点不同,需要通过别名的方式引用。修改examples/pckage.json

1
2
3
4
// examples/pckage.json
"dependencies": {
"doraemon": "workspace:*"
}

接下来安装包:

1
2
cd examples
pnpm i

在main.js中引用doraemon:

1
2
3
4
5
6
7
8
9
10
11
// main.js
import { logger } from 'doraemon'

logger({ 'a': 3, 'b': 2 })


// src/index.js
// 修改一下函数的导出方式
export function logger(data) {
console.log(JSON.stringify(data, null, 4))
}

启动示例:

1
2
// examples
pnpm dev

访问http://127.0.0.1:3000/,并打开浏览器调试工具,查看输出,提交代码。

我们一直在写代码,现在暂停一下,说明为什么使用pnpm。使用pnpm是为了更快的速度和非扁平化的依赖目录。

pnpm的速度

先看一下pnpm官网的性能对比图,pnpm会在全局存储下载过的包,提高二次下载的速度。

pnpm依赖的目录结构

再来看一下pnpm与npm的node_modules目录结构的差异。
假设项目需要A、B、C、D四个依赖,A与B同时依赖X0.0.1,C与D同时依赖X0.0.2。

非扁平的目录

使用pnpm安装后,node_modules下只有ABCD。而使用npm和yarn安装,node_modules还多出了X0.0.1依赖。

我们日常项目的node_modules会出现更多的依赖,这个问题被成为了幽灵依赖(包没有出现在package.json,却依然能使用)。

子依赖的多版本问题

再看子依赖的处理方式,使用pnpm多了一个.pnpm目录,将子依赖按照名字+版本号的方式都放到了这里,pnpm使用软链接的方式,将本项目的依赖指向了真实存储的全局依赖。结果是占用更少的硬盘资源。

npm的处理子依赖的方式是,X0.0.1因为被依赖了两次,所以被提升到了node_modules下,由于X0.0.1已经被提升了,所以X0.0.2只能在各自父级目录被下载,总共下载了两次。这也是pnpm速度快的原因之一。

打包

继续编码,目前我们的源码src下只有index.js一个文件,显然不能把所有的代码都放到一个文件中。方法越来越多,需要划分模块。那么此时就要所有代码打包成一个文件。

先修改源码,新建logger.js和uuid.js,你也可以创建自己想要的模块。

1
2
3
4
5
6
7
8
9
10
// logger.js
export function logger(data) {
console.log(JSON.stringify(data, null, 4))
}

// uuid.js
// 生成随机id
export function randomId (len) {
return Math.random().toString(36).substr(3, len)
}

在index.js中导出所有包。

1
2
3
// index.js
export * from './logger'
export * from './uuid'

使用esbuild来打包,安装依赖,注意有个-w。

1
2
// 根目录
pnpm i esbuild -D -w

增加构建命令,将代码打包到dist目录下,并修改库入口。

1
2
3
4
5
6
// package.json

"main": "dist/index.js",
"scripts": {
"dev": "pnpm esbuild src/index.js --bundle --outdir=dist --format=esm --watch"
},

在根目录运行

1
pnpm dev

在examples中使用一下randomId方法。

1
2
3
4
5
6
// examples/main.js
import { logger, randomId } from 'doraemon'

logger({ 'a': 3, 'b': 2 })

console.log(randomId(16))

访问http://127.0.0.1:3000/。

在.gitignore中忽略dist目录,提交代码。

1
2
3
.vscode
.idea
dist

我们目前的构建是开发模式下的,下一节我们将区分开发和生产时的构建。

源码:https://github.com/hanmingpan/blog-demonstration/tree/main/doraemon/day2

推荐阅读