开发npm包

前提:

  • node已经安装(v14.20.0)、npm下载了源(https://registry.npmjs.org/)

目的:

  • 发布自己的插件用于项目中

创建项目

  • 创建文件夹
mkdir hell-lib
  • 进入文件夹
cd hello-lib
//初始化成为一个node项目(初始化后生成一个package.json文件)
npm init -y
  • package.json
 { 	
 	//这个名称是项目名称-后面会与发布有关
	  "name": "@learningvue3/lib",
	  "version": "1.0.0",
	  "description": "A library demo for learningvue3.",
	  "author": "chengpeiquan <chengpeiquan@chengpeiquan.com>",
	  "homepage": "https://github.com/learningvue3/hello-lib",
	  "repository": {
	    "type": "git",
	    "url": "git+https://github.com/learningvue3/hello-lib.git"
	  },
	  "license": "MIT",
	  "files": ["dist"],
	  "main": "dist/index.cjs",
	  "module": "dist/index.mjs",
	  "browser": "dist/index.min.js",
	  "types": "dist/index.d.ts",
	  "keywords": ["library", "demo", "example"],
	  "scripts": {
	    "build": "vite build"
	  }
}
  • 在该项目下全局下载vite
npm i -D vite
  • 添加配置文件
// vite.config.ts
import { defineConfig } from 'vite'

// https://cn.vitejs.dev/config/
export default defineConfig({
  build: {
    // 输出目录
    outDir: 'dist',
    // 构建 npm 包时需要开启 “库模式”
    lib: {
      // 指定入口文件
      entry: 'src/index.ts',
      // 输出 UMD 格式时,需要指定一个全局变量的名称
      name: 'hello',
      // 最终输出的格式,这里指定了三种
      formats: ['es', 'cjs', 'umd'],
      // 针对不同输出格式对应的文件名
      fileName: (format) => {
        switch (format) {
          // ES Module 格式的文件名
          case 'es':
            return 'index.mjs'
          // CommonJS 格式的文件名
          case 'cjs':
            return 'index.cjs'
          // UMD 格式的文件名
          default:
            return 'index.min.js'
        }
      },
    },
    // 压缩混淆构建后的文件代码
    minify: true,
  },
})
  • 创建入口文件
//根据配置文件的信息我们需要在项目下创建入口文件=》src/index.ts
// src/index.ts
export default function hello(name: string) {
  console.log(`Hello ${name}`)
}
  • 构建项目
npm run build
  • 生成如下项目
hello-lib
│ # 构建产物的输出文件夹
├─dist
│ ├─index.cjs
│ ├─index.min.js
│ └─index.mjs
│ # 依赖文件夹
├─node_modules
│ # 源码文件夹
├─src
│ │ # 入口文件
│ └─index.ts
│ # 项目清单信息
├─package-lock.json
├─package.json
│ # Vite 配置文件
└─vite.config.ts

编写npm包代码

1、前期准备
  • 创建utils.ts(后面需要发布的内容)
// src/utils.ts

/**
 * 生成随机数
 * @param min - 最小值
 * @param max - 最大值
 * @param roundingType - 四舍五入类型
 * @returns 范围内的随机数
 */
export function getRandomNumber(
  min: number = 0,
  max: number = 100,
  roundingType: 'round' | 'ceil' | 'floor' = 'round'
) {
  return Math[roundingType](Math.random() * (max - min) + min)
}

/**
 * 生成随机布尔值
 */
export function getRandomBoolean() {
  const index = getRandomNumber(0, 1)
  return [true, false][index]
}
  • 创建入口
//src/index.ts
export * from './utils'
  • npm run build

可以看到构建的dist的文件中编译后的信息就是npm包内容了

2、npm包本地测试(重点)
  • 创建本地软链接
 //创建npm包的本地链接
 npm link
 //终端执行完会生成:
 //(node_modules/@learningvue3/lib中的@learningvue3是package.json中的name)
 // /Users/XXX/.nvm/versions/node/v14.20.0/lib/node_modules/@learningvue3/lib -> /Users/XX/XX/project/vue3/npm/hello-lib
  • 在别的vue项目中根据软链接下载该项目包进行发布前的本地测试(@learningvue3/lib)
//链接下载@learningvue3/lib
npm link @learningvue3/lib
//然后在该vue的node-module中可以看到该包已经在了,然后就可以调用方法了
  • 测试(在vue项目下载@learningvue3/lib后就可以直接引入调用如下方法)
//注意@learning-vue3/lib会报红色波浪线(下一步会解决:生成DTS文件)
import { getRandomNumber } from '@learning-vue3/lib'

const num = getRandomNumber()
console.log(num)
生成 DTS 文件
  • typescript(hello-lib)
//安装
npm install -g typescript
//编译生成-tsconfig.json
tsc --init
  • tsconfig.json修改以下几项配置
//其中 compilerOptions 三个选项的意思是:
// .ts 源文件不编译为 .js 文件,
// 只生成 .d.ts 文件并输出到 dist 目录; 
// include 选项则告诉 TypeScript 编译器,只处理 src 目录下的 TS 文件。
{
  "compilerOptions": {
  	
    "declaration": true,
    "emitDeclarationOnly": true,
    "declarationDir": "./dist"
  },
  "include": ["./src"]
}

  • 编译
//编译后在dist中会看到 .d.ts 后缀文件
tsc
//去测试的vue项目中 执行 npm run build 就会看到 红色波浪线取消了
  • hello-lib 项目的 package.json 已提前指定了类型声明文件指向:
{
  "types": "dist/index.d.ts"
}

注意

由于上述的方式会导致每个文件都会生成一个.d.ts 声明文件,不是很好的解决方式,常用以下方式解决

生成 DTS Bundle
  • 安装
npm i -D dts-bundle-generator
  • 创建文件(文件夹scripts, 目录下再创建 buildTypes.mjs )
// scripts/buildTypes.mjs
import { writeFileSync } from 'fs'
import { dirname, resolve } from 'path'
import { fileURLToPath } from 'url'
import { generateDtsBundle } from 'dts-bundle-generator'

async function run() {
  // 默认情况下 `.mjs` 文件需要自己声明 __dirname 变量
  const __filename = fileURLToPath(import.meta.url)
  const __dirname = dirname(__filename)

  // 获取项目的根目录路径
  const rootPath = resolve(__dirname, '..')

  // 添加构建选项
  // 插件要求是一个数组选项,支持多个入口文件
  const options = [
    {
      filePath: resolve(rootPath, `./src/index.ts`),
      output: {
        noBanner: true,
      },
    },
  ]

  // 生成 DTS 文件内容
  // 插件返回一个数组,返回的文件内容顺序同选项顺序
  const dtses = generateDtsBundle(options, {
    preferredConfigPath: resolve(rootPath, `./tsconfig.json`),
  })
  if (!Array.isArray(dtses) || !dtses.length) return

  // 将 DTS Bundle 的内容输出成 `.d.ts` 文件保存到 dist 目录下
  // 当前只有一个文件要保存,所以只取第一个下标的数据
  const dts = dtses[0]
  const output = resolve(rootPath, `./dist/index.d.ts`)
  writeFileSync(output, dts)
}
run().catch((e) => {
  console.log(e)
})
  • 运行buildTypes.mjs需要在package,json添加执行命令如下
{
  "scripts": {
    "build": "vite build && npm run build:types",
    "build:types": "node scripts/buildTypes.mjs"
  }
}
  • npm run build
hello-lib
└─dist
  ├─index.cjs
  ├─index.d.ts
  ├─index.min.js
  └─index.mjs
  • 添加说明文档:(选用README .md,模版如下)
# 项目名称

写上项目用途的一句话简介。

## 功能介绍

1. 功能 1 一句话介绍
2. 功能 2 一句话介绍
3. 功能 3 一句话介绍

## 在线演示

如果有部署在线 demo ,可放上 demo 的访问地址。

## 安装方法

使用 npm : `npm install package-name`

使用 CDN : `https://example.com/package-name`

## 用法

告诉使用者如何使用 npm 包。

## 插件选项

如果 npm 包是一个插件,并支持传递插件选项,在这里可以使用表格介绍选项的作用。

| 选项名称 |  类型  |    作用    |
| :------: | :----: | :--------: |
|   foo    | string | 一句话介绍 |
|   bar    | number | 一句话介绍 |

更多内容请根据实际情况补充。
npm 注册
  • 注册:https://www.npmjs.com
  • 创建npm项目(https://www.npmjs.com/package)
    在这里插入图片描述
    在这里插入图片描述
    注意:
  • 这里的Name要与你发布的npm项目package.json相关
  • 比如package,json的name是@learningvue3/lib,则npm创建的name就可以是learningvue3
  • 不然的话会在发布的时候报错404(我的是这样解决的)
  • 项目登陆

在你发布的npm的项目下打开终端进行命令登陆

npm login
//执行后会有填写账号密码邮箱和校验码信息
  • npm 发布
npm publish --access public  

注意

报错403

  • 查看npm源是不是https://registry.npmjs.org/

报错404

  • 查看项目的package.json中的name与npm创建的组织名称是否对应
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值