⚡如何设计与实现一个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

相关推荐
熊的猫40 分钟前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
瑶琴AI前端1 小时前
uniapp组件实现省市区三级联动选择
java·前端·uni-app
会发光的猪。1 小时前
如何在vscode中安装git详细新手教程
前端·ide·git·vscode
我要洋人死2 小时前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人3 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人3 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR3 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香3 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596933 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai3 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书