⚡如何设计与实现一个npm包

npm(Node Package Manager)是Node.js的包管理工具,用于帮助开发人员在项目中安装、管理和发布JavaScript包。开发人员可以使用npm来查找并安装各种功能模块,以便在项目中使用。

众所周知,前端人都离不开npm包,如前端框架Vue,React,工具函数Lodash,mitt等在现代开发模式中你想使用它们,你需要使用它们的npm包并引入。

如今npm上托管的包数量有近300万,周下载量近600万,可见前端根本离不开npm!

今天就教大家设计与开发一个属于自己的npm包。

1. npm包的功能

我们使用的每一个npm包,它都会有自己的用处,我们这次打算开发一个区分变量类型的包,比较轻量。

众所周知,区分变量类型的方法有typeOfinstanceOf,但是它们都有各自的缺点。

我们可以借助Object.prototype.toString来辨别函数类型。

js 复制代码
Object.prototype.toString.call(1); // '[object Number]'
Object.prototype.toString.call('a') // '[object String]'
Object.prototype.toString.call([1,2,3]) // '[object Array]'

这个包的名称我把它叫做typeoff

2. 代码实现

这里我们希望我们的npm包使用时具有类型提示,因此我们使用TS来开发

创建项目

使用npm create vite创建ts项目

执行npm i安装依赖

我们打开main.ts,清空代码,接下来编写我们的代码。文件重命名index.ts

ts 复制代码
const objectToString = Object.prototype.toString
const toTypeString = (value: unknown): string =>
  objectToString.call(value)

export const isArray = Array.isArray

export const isMap = (val: unknown): val is Map<any, any> =>
  toTypeString(val) === '[object Map]'

export const isSet = (val: unknown): val is Set<any> =>
  toTypeString(val) === '[object Set]'

export const isDate = (val: unknown): val is Date =>
  toTypeString(val) === '[object Date]'

export const isRegExp = (val: unknown): val is RegExp =>
  toTypeString(val) === '[object RegExp]'

export const isFunction = (val: unknown): val is Function =>
  typeof val === 'function'

export const isString = (val: unknown): val is string => typeof val === 'string'

export const isSymbol = (val: unknown): val is symbol => typeof val === 'symbol'

export const isObject = (val: unknown): val is Record<any, any> =>
  val !== null && typeof val === 'object'

export const isPromise = <T = any>(val: unknown): val is Promise<T> => {
  return (
    (isObject(val) || isFunction(val)) &&
    isFunction((val as any).then) &&
    isFunction((val as any).catch)
  )
  
}

目前我们的函数支持了常见的类型判断了,如何把这些函数弄成一个npm包供大家使用呢。

打包以及混淆压缩代码

由于我们写的是Ts代码,在浏览器里是跑不了的,需要转换成js,有高级的语法还需要转成ES5,ES6的语法。

通常我们会借助babel 等工具,但是我这里推荐另外一个比较好用轻量的构建工具:unbuild

正如它的标题,一个统一的JavaScript构建系统,它支持支持 typescript 并生成 commonjs 和模块格式 + 类型声明。

就我使用一段时间而言,我感觉上手容易,配置简单,Vite源码也是借助于该库打包,还是比较可靠的。接下来我们一起配置它。

安装依赖

bash 复制代码
npm i unbuild -D

配置文件

根目录文件:build.config.ts

ts 复制代码
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
  entries: ["src/index"],
  clean: true,
  rollup: {
    inlineDependencies: true,
    esbuild: {
      target: "ES6",
      minify: true,
    },
  },
  declaration: true, // 添加类型声明
});

脚本配置

json 复制代码
{
  "scripts": {
    "build": "unbuild"
  },
}

执行npm run build

看,我们已经成功输出编译后的代码。

npm发布准备

在发布之前,我们还需要修改一下package.json中的内容

需要加上下面这些内容,npm平台才能识别你的代码

json 复制代码
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/index.mjs"
    }
  },
  "main": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "files": ["dist"],

3.发布npm包

首先我们需要把 NPM 的源设置成你想要的,一般都是设置为公司的私有仓库地址,但是这里我设置为公共仓库~

bash 复制代码
npm config set registry https://registry.npmjs.org/

接着我们需要登录 NPM ,进行身份认证~

需要填写这些信息:

  • username:npm 的用户名
  • password:npm 的密码
  • email:npm 注册的邮箱
  • one-time password:邮箱接收的验证码

然后运行npm publish

这里有一点小问题

我们需要把package.json中的private属性设为false或者去掉

接下来再执行npm publish

发布成功!!! 我们在npm官网搜索该包:

看,现在就有了,我们创建一个项目试试吧

看,现在可以成功引入函数了,而且有类型提示,非常的舒服~

ts 复制代码
import { isArray, isFunction, isObject, isSet } from 'typeoff';
console.log('isArray', isArray([1, 2, 3]));
console.log(
  'isFunction',
  isFunction(() => console.log('isFunction'))
);
console.log('isObject', isObject({}));
console.log('isSet', isSet(new Set()));

Nice~现在我们成功发布了一个npm包typeoff,大家可以安装来体验一下

bash 复制代码
npm i typeoff

大家以后做类型判断的时候就可以引入来用哇。

这里的源码提供给大家,可供大家学习,star可以帮我点一下

项目地址:github.com/Awu1227/typ...

npm地址:www.npmjs.com/package/typ...

demo:stackblitz.com/edit/vitejs...

最后

本文介绍了如何设计与实现一个npm包~,是不是感觉蛮简单的呢,关注我,干货下期继续放送😋

如果这篇文章对你有帮助的话,麻烦点赞收藏哟~

笔者还有其他专栏,欢迎阅读~
Vue从放弃到入门
深入浅出JavaScript

相关推荐
桃园码工15 分钟前
15_HTML5 表单属性 --[HTML5 API 学习之旅]
前端·html5·表单属性
百万蹄蹄向前冲1 小时前
2024不一样的VUE3期末考查
前端·javascript·程序员
轻口味1 小时前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami1 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
吃杠碰小鸡2 小时前
lodash常用函数
前端·javascript
emoji1111112 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼2 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250032 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O2 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235952 小时前
web复习(三)
前端