如何快乐地使用vite开发npm库(typescript),搭建·调试·发布·闭环式教程

使用vite开发npm依赖,闭环式教程

本教程将:

  • 介绍如何搭建一个vite项目,并配置为库模式,为esmodule、umd打包出对应语法的两套js文件。
  • 用typescript开发库时,如何在vite中自动生成声明文件呢。
  • 然后,也会介绍package.json中与库相关的属性,这些属性决定了哪些文件会发布到npm上,以及当别人导入你的库时,会拿哪个文件给人家。
  • 在发布到npm之前,如何测试呢,这里会介绍npm一些关于软链接npm link相关的命令,让你在本地提前安装上要发布的库并使用。也会介绍热更新式的调试模式,提升开发体验!
  • 最后,我们平时一般使用淘宝镜像源来下载npm依赖。但是要登陆和发布,就必须切换到npm官方源,通过npm配置修改的话会很繁琐,所以会介绍更简单的方式。
  • 整个流程中的一些坑也会在介绍中提示。

前置知识-关于包名

任何库的库名都是对应package.json里的name属性值(与文件名,导出什么模块没关系),安装第三方依赖库时,也是通过它来找到该库,所以如果要发布到npm上,name值必须是npm上没有发布过的。

# npm info packagename 命令,查找npm上名为packagename的依赖,
# 找到了会返回版本信息,可用它来看看自己要发布的包是否被发布过了

npm info packagename 

既然库名和代码没任何关系,那import xxx from packagename时,是怎么找到对应的模块所在的js文件的呢? 答案在package.json里,它的main、module`属性值保存了不同导入方式,指向哪个js文件的信息。

下面介绍中用到的packagename就是指代package.json里的name值。

搭建vite项目来打包库

  1. 初始化项目目录,然后安装vue、vite为开发依赖,这里假设是开发vue生态的插件:

    # 创建一个项目目录,并初始化,可以自己手动创建
    mkdir gr-lib && cd gr-lib && mkdir src && npm init -y
    
    
    
    
    # 开发库时,是不需要把vue打包进来,安装为开发依赖即可
    npm i vue vite -D
    
  2. 创建vite.config.js,并配置为库模式,可百度vite官网查看,官方介绍还是很详细的:

    import { resolve } from 'path'
    import { defineConfig } from 'vite'
    ​
    
    export default defineConfig({
    
      // vite默认会打包出umd和esmodule两种导出方式的文件,以下配置会打包出两份结果:
      // gr-lib.umd.js umd导出方式,兼容amd commenjs
      // gr-lib.mjs esmodule导出方式
      build: {
        lib: {
          entry: resolve(__dirname, './src/gr-lib.ts'),
          name: 'grLib',
          // 构建好的文件名(不包括文件后缀)
          fileName: 'gr-lib',
        },
        rollupOptions: {
          // 确保外部化处理那些你不想打包进库的依赖
          external: ['vue'],
          output: {
            // 在 UMD 构建模式下,全局模式下为这些外部化的依赖提供一个全局变量
            globals: {
                grLib: 'grLib',
            },
          },
        },
      },
    })
    

自动生成dts声明文件

配置好vite.config.js后,就可以构建了。但是如果是使用ts开发库,则需要配置自动生成dts声明文件,有两种方式(推荐第二种)。当然也可以自己手写。

  1. 方式一:自己安装typescript并配置tsconfig.js

    首先,安装依赖并生成tsconfig.json

    # 安装tsc依赖
    npm i typescript -D
    # 自动生成tsconfig.json
    npx tsc --init
    

    然后,修改生成的tsconfig.json,让tsc命令只生成声明文件,不转译ts文件:

    {
        "compilerOptions":{
            // ...其它配置
            "declaration": true, // 自动生成声明文件
            "declarationDir": "dist", // 声明文件输出的目录
            "emitDeclarationOnly": true, // 只输出声明文件,不转译ts文件
        }
    }
    

    最后,在执行vite构建命令时,同时执行一下tsc来生成声明文件:

    vite build && tsc
    
  2. 方式二:使用vite插件,执行vite命令时,会一并生成声明文件。如vite-plugin-dts插件。

    首先,安装vite-plugin-dts依赖:

    # 下载vite-plugin-dts插件
    npm i vite-plugin-dts -D
    

    然后,在vite中引入该插件,并注册:

    • 该插件会默认读取根目录tsconfig.json的部分配置,但入口文件,输出目录会和vite构建输出目录一致。
    // vite.config.js
    import dts from 'vite-plugin-dts'
    ​
    
    export default defineConfig({
    
      // ...
      // 该插件支持传递配置项
      // 如配置: dts({ tsconfigPath: './tsconfig.json '}),表示读取tsconfig.json的include、exlude配置
      plugins: [dts()],
    })
    

    最后,直接执行vite构建命令,即可同时生成声明文件:

    vite build
    

    注:上面两种方式,生成的声明文件,是和文件名对应的,如my-lib.ts => my-lib.d.ts

    vite配置的库入口文件build.lib.filename最好和库名一致,这样声明文件名的头部名字和库名可以对上,否则可能出现库被安装后找不到对应声明文件的问题

配置package.json指定库信息

上面的步骤中,vite的作用有两个:

一、为不同导出规范,打包出对应的js文件(模块),如esmodule和umd。

二、生成对应的dts声明文件。

打包好了构建结果,还不能称为一个npm库,还缺少库的描述信息,如库名、版本、不同导入方式返回哪个文件等信息。这些信息都需要在package.json的对象里定义。

当一个业务项目中(通过npm下载)导入一个库时,是导入它提供的esmodule的文件还是umd的文件呢,这就需要读取package.json的main和module属性来决定。

  • main属性值是非esmodule导入时,导入的文件,所以需要指定为构建好的umd语法的js文件路径。
    // 以下语句会导入main属性值指定的文件
    require('packagename')
    
  • module属性值是esmodule导入时,导入的文件,指定为构建好的esmodule语法的mjs文件路径。
    // 以下语句会导入module属性值指定的文件
    import xx from 'packagename'
    

如果有dts声明文件(上面有介绍如何自动生成),还需要指定声明文件路径:

  • typings:声明文件的路径。

另外还有三个与发布相关的属性:

  • name:库名,在npm上必须唯一,否则无法发布,别人也是通过该库名来执行下载npm install的。
  • files:指定哪些文件要发布到npm上,一般指定为构建输出目录,如dist。因为vite.config.js等配置文件是不需要发布的。人家安装你的库,结果把一堆开发用的配置文件下下来了,没有必要。
  • version:指定当前库的版本。每次发布都要把版本提高一下,否则无法发布到npm上。

package.json

   {
     "name": "gr-lib", // 安装该库时,的库名字
     "version": "0.0.2", // 当前库的版本
     "main": "dist/gr-lib.umd.js", // 非esmodule方式导入时的文件
     "module": "dist/gr-lib.mjs", // esmodule导入时的文件
     "typings": "dist/gr-lib.d.ts", // 声明文件地址,否则导入模块不识别类型
     "files": [
       "dist" // 要发布的文件,发布后只会提交dist目录里的所有文件,还有package.json文件
     ]
   }
   

发布前调试

开发库时,如果不想参入太多其它代码,只有库自己的实现,但又想看看它的运行情况。最好的调试方式就是,将它安装到具体项目中测试,模拟真实的环境。但是正在开发的库,在还没发布到npm之前如何安装到项目中调试呢?

可以给正在开发的库创建一个软链接,并把软链接放到你全局的node_modules目录中。相当于把它变成一个本地全局依赖。然后启动一个演示项目demo,可以通过npm link packagename来安装该库。并且demo中是实时同步开发中的库的更改的,无需重复创建软链接和重新安装。

首先,为已经构建好的库(已经构建好了产物、package.json也配置了),在你的全局node_modules目录中生成一个软链接:

  1. 在库目录下,执行:

    # 为该库创建一个本地全局可见的软链接,可以在全局的node_modules目录里找到它。
    npm link
    
    
    
    
    # 删除该全局软连接
    npm unlink
    # 如果想要在任意目录下删除该全局软链接
    # PS:不加 -g 则默认只删除pwd目录下的该依赖,不会访问全局的node_modules
    npm unlink packagename -g
    
  2. 查看全局依赖目录下都安装了哪些依赖,来判断是否在全局成功创建、删除全局软连接:

    # 查看全局node_modules目录中是否有该依赖(软链接的方式存在),ls是list的简写
    npm ls -g
    # 指定依赖查找深度为0,查找会更快一点点
    npm ls -g --depth 0
    
    # 如果全局依赖太多,只想看某个库是否安装了
    npm ls packagename -g
    

然后,在本地的demo项目中,“下载”该库。

  1. demo项目,安装该开发中的库:

    # 安装:这里link相当于install
    npm link packagename
    
    
    
    
    # 从demo项目的node_modules目录中删除该库,
    # 但库的软链接还是会留在全局的node_modules目录中
    npm unlink packagename
    
  2. 查看demo项目中,是否成功安装该库:

    npm ls packagename : 可以查看依赖在项目中的被依赖关系及对应的版本。

    npm ls packagename
    

构建热更新

demo项目通过软链接安装该库后,每当库项目打包好,都可以实时同步更改,无需重复卸载安装该库。我们要做到就是,改一次库的代码就执行一下构建命令,demo项目也会同步最新的库文件。但每次都要手动构建会很麻烦。

可以在执行打包时,监听文件的变化,当文件变化后,立马构建,解放双手:

# 执行打包后,控制台不会退出,而是监听文件变化,并自动构建
vite build --watch

注意:只能和自动生成dts的第二种方式搭配使用,因为频繁构建会把tsc生成的声明文件删除

发布到npm上

通过以上步骤构建好了产物、dts声明文件,并把库信息更新到了package.json里后,测试也没问题了,就可以发布到npm上啦!

当配置了淘宝镜像源,是无法登录到npm的,只需要指定官方源即可。

首先,库项目目录下,执行登录命令,然后根据提示输入账号密码即可:

# 如果是使用npm官方源,直接使用npm login命令即可
npm login --registry https://registry.npmjs.org

登录成功后,执行发布命令:

# 如果登录过,每次发版,直接publish即可
npm publish --registry https://registry.npmjs.org




# 撤销发布某个版本:package.json中对应version的版本
npm unpublish --force --registry https://registry.npmjs.org

为了方便,可以把这些命令配置到package.json的scripts中。

注意执行publish的命令的属性名,不能是publish,因为执行npm run publish会执行两次发布

package.json

 "scripts": {
    "build": "vite build",
    "build:watch": "vite build --watch",
    "pushnpm": "npm publish --registry https://registry.npmjs.org"
  },

第一次发版、后续的版本更新都通过以下命令发布即可,发布成功后会有邮件提示的。

npm run pushnpm

最后,不要忘了给你的库添加一个readme.md的文件,向大家介绍你的库怎么用,用你的库会收获哪些快乐等。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYRLM6Fr' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片