vue3组件库项目学习笔记(四):发布你的组件

news/2023/6/9 20:09:31

在完成我们的组件之后,我们肯定希望可以将它发布到 npm 等地,这样任何人都可以使用它了,这里我们使用 gulp 这个工具来自动化打包和发布我们的组件库

引入gulp

我们还是首先导入需要的依赖

pnpm i gulp @types/gulp sucrase -D -w

之后我们在根目录的 package.json 中添加打包组件库命令

 "scripts": {"build": "gulp -f packages/components/script/build.ts"}

然后我们创建 packages/components/script/build.ts 这个文件并且编写一些简单的测试

export default () => {console.log('test')return Promise.resolve()
}

我们运行 pnpm run build 命令,如果输出 test 说明我们引入工具成功

删除上一次的内容

发布内容我们要做的第一件事情就是删除上一次打包的结果,众所周知,vite打包生成的是 dist 文件夹,所以我们要做的就是删除上一次打包产生的痕迹,我们开始编写一个脚本来完成这个操作:

首先我们编写一个方法来拿到我们的打包的根目录,也就是 components 文件夹,将他放在 script/utils.ts 文件中,作为我们的公共方法,因为其他模块也需要这个方法:

import { resolve } from 'path'export const componentPath = resolve(__dirname, '../')

之后我们在 script/build.ts 中编写我们的脚本,这个脚本很简单,我们编写了一个 run 函数,它的作用就是在命令行运行我们提供的脚本,脚本内容是 rimraf ${componentPath}/dist 就是删除根目录下的dist文件夹,注意如果你在 linux环境下开发,你可以使用 rm -rf 命令,在window下开发的话,我们使用了 node 中一个模块来帮助我们完成这个操作,当然这个模块需要我们安装 pnpm i rimraf -w

import { spawn } from 'child_process'
import { series } from 'gulp'
import { componentPath } from './utils'const run = async (command: string) => {//获得我们的指令const [cmd, ...args] = command.split(' ')return new Promise((resolve, reject) => {const app = spawn(cmd, args, {cwd: componentPath,//执行命令的路径stdio: 'inherit', //输出共享给父进程shell: true})//执行完毕关闭并resolveapp.on('close', resolve)})
}
//运行指令来删除我们的dist文件夹
export default series(async () => run(`rimraf ${componentPath}/dist`))

现在我们在 components文件夹创建一个 dist 文件夹,然后根目录运行脚本,如果文件夹被删除说明我们的脚本成功了

打包组件库

我们对于组件库的打包分为两个部分,首先是打包我们的样式文件,之后我打包组件库本身

  • 打包样式

首先我们下载处理 less 的打包依赖

pnpm i gulp-less @types/gulp-less gulp-autoprefixer @types/gulp-autoprefixer -D -w

之后我们在 打包脚本中编写样式构建的相关内容:我们编写一个函数来处理样式,先定位到样式所在的位置,然后将样式打包处理后输出到指定位置,我们运行脚本,人工看到在components 文件夹下出现了 dist 目录并且里面含有样式文件,说明我们的打包成功了:

import { spawn } from 'child_process'
import { series, src, dest, task } from 'gulp'
import { componentPath } from './utils'
import less from "gulp-less"
import autoprefixer from 'gulp-autoprefixer'/**   **/
//处理样式
const buildStyle = () => {return src(`${componentPath}/src/**/style/**.less`).pipe(less()).pipe(autoprefixer()).pipe(dest(`${componentPath}/dist/lib/src`)).pipe(dest(`${componentPath}/dist/es/src`));
};export default series(async () => run(`rimraf ${componentPath}/dist`),async () => buildStyle())
  • 打包组件

众所周知,打包组件的配置在 vite 中配置的,所以我们需要配置我们的 vite.config.ts 文件,其作用是将我们的源代码打包成发布需要的文件:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"
import dts from 'vite-plugin-dts'
import { resolve } from 'path'
export default defineConfig({build: {target: 'modules',//打包文件目录outDir: "es",emptyOutDir:false,//压缩minify: true,//css分离//cssCodeSplit: true,rollupOptions: {//忽略打包vue文件external: ['vue', /\.less/,'@ls-ui/utils'],input: ['src/index.ts'],output: [{format: 'es',//不用打包成.es.js,这里我们想把它打包成.jsentryFileNames: '[name].js',//让打包目录和我们目录对应preserveModules: true,//配置打包根目录dir: resolve(__dirname, './dist/es'),preserveModulesRoot: 'dist'},{format: 'cjs',//不用打包成.mjsentryFileNames: '[name].js',//让打包目录和我们目录对应preserveModules: true,//配置打包根目录dir: resolve(__dirname, './dist/lib'),preserveModulesRoot: 'src'}]},lib: {entry: './index.ts',formats: ['es', 'cjs']}},plugins: [vue(),dts({outputDir: resolve(__dirname, './dist/es/src'),//指定使用的tsconfig.json为我们整个项目根目录下掉,如果不配置,你也可以在components下新建tsconfig.jsontsConfigFilePath: '../../tsconfig.json'}),//因为这个插件默认打包到es下,我们想让lib目录下也生成声明文件需要再配置一个dts({outputDir: resolve(__dirname, './dist/lib/src'),tsConfigFilePath: '../../tsconfig.json'}),{name: 'style',generateBundle(config, bundle) {//这里可以获取打包后的文件目录以及代码codeconst keys = Object.keys(bundle)for (const key of keys) {const bundler: any = bundle[key as any]//rollup内置方法,将所有输出文件code中的.less换成.css,因为我们当时没有打包less文件this.emitFile({type: 'asset',fileName: key,//文件名名不变source: bundler.code.replace(/\.less/g, '.css')})}}}],resolve: {alias: {'@': resolve(__dirname, 'src'),},}}
)

之后我们修改我们的 package.json 文件,添加 build 方法,并且完善一些细节

{"name": "ls-ui","version": "1.0.1","main": "index.ts","scripts": {"build": "vite build"},"files": ["es","lib"],"keywords": ["ls-ui",],"author": "zs","license": "MIT","description": "","typings": "lib/index.d.ts","dependencies": {"@ls-ui/utils": "workspace:^1.0.1"}
}

在有了打包命令以后,我们在脚本文件里添加一个方法来打包我们的组件,这个方法就是执行刚刚添加的 build 命令

const buildComponent = async () => {await run(`cd ${componentPath}`);run("pnpm run build");
};export default series(async () => run(`rimraf ${componentPath}/dist`),async () => buildStyle(),async () => buildComponent()
);

之后我们只要在根目录运行打包命令就可以完成我们组件的打包,如果成功打包可以看到出现了 dist 文件,其中有 es 和 lib 两个文件夹

发布组件

在有了一个完成打包的文件夹后之后,我们希望将我们打包完成的组件库发布到 npm ,我们添加一个脚本来完成我们的发布工作,取名为 publish.ts 放在与 build.ts 同一个目录下,这个脚本的作用是,为我们的组件库添加一个 package.json 文件,然后使用 npm 的发布功能发布我们的组件:

import { spawn } from 'child_process'
import { series, src, dest } from 'gulp'
import { componentPath } from './utils'
const run = async (command: string, path: string) => {const [cmd, ...args] = command.split(' ')return new Promise((resolve, reject) => {const app = spawn(cmd, args, {cwd: path,//执行命令的路径stdio: 'inherit', //输出共享给父进程shell: true //mac不需要开启,windows下git base需要开启支持})app.on('close', resolve)})
}
//复制
const copypackage = async () => {return src(`${componentPath}/transitpkg/**`).pipe(dest(`${componentPath}/dist/`));
};
//发布任务
const publish = async () => {await run('pnpm version patch', `${componentPath}/transitpkg`)//复制到dist目录await copypackage()//在dist下执行发布命令await run('npm publish', `${componentPath}/dist`)
}
export default series(async () => publish()
)

为了实现这个脚本,我们现在根目录添加运行我们这个脚本命令

"scripts": {"publish": "gulp -f packages/components/script/publish.ts"},

之后我们在 components 文件夹下新建一个 transitpkg 文件夹,在其中添加一个 package.json 文件:

{"name": "ls-ui","version": "1.0.1","main": "lib/index.js","module": "es/index.js","files": ["es","lib"],"keywords": ["ls-ui",],"author": "zs","license": "MIT","description": "","typings": "lib/index.d.ts"
}

我们的脚本就是把这个文件复制到dist内,之后将这个包含配置信息的包发布到 npm 官方,在发布之前,我们需要先登录自己的账号,我们需要先登录官方账号注册一个账号(https://www.npmjs.com/),之后在命令行登录:

npm login

在登录成功后运行我们的发布脚本就可以发布我们的组件了

pnpm run publish

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4557821.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

初学者C语言练习题-入门

一、入门 C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进入编程世…

Android 震动马达系统

转自:http://www.cnblogs.com/skywang12345/p/3404808.html 在Android 2.3(Gingerbread) 系统的时候,我写过一篇关于“Android 震动马达系统“的文章,当时的Linux内核还是2.6版本的。写那篇文章的目的,是想彻底的了解从硬件到驱动…

一篇五分生信临床模型预测文章代码复现——Figure 4-6 临床模型构建(八)

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

Android端视频播放器源码分析

这篇文章主要是分析视频播放器的实现代码。代码地址:查看 整体设计框架 我们播放本地的视频文件需要封装出一个输入模块: 输入模块要开启一个线程来处理解封装和解码,把得到的裸数据放到音频和视频的队列中。输出模块: 输出为…

Qt5 QML 实现一个简易的录音组件

0.前言 Qt 的 multimedia 多媒体模块提供了一些基本的音视频接口,虽然不带编解码器,不过对于录音来说,能处理 PCM 数据就够了。实现中,使用 QAudioDeviceInfo 获取输入输出设备信息,使用 QAudioInput 获取音频输入数据…

声网 VQA:将实时互动中未知的视频画质用户主观体验变可知

在实时互动场景中,视频画质是影响观众体验的关键指标,但如何实时评价视频的画质一直是个行业难题,需要将未知的视频画质用户主观体验变成可知。 未知的部分往往是最需要攻克的,声网也一直在持续探索符合实时互动领域的视频画质评…

FFmpeg之ffplay源码简要分析

1 ffplay 基本架构 1.1 视频解码播放的基本流程 ffmpeg视频解码播放的基本流程如下图所示: 首先对网络媒体数据流进行解封装得到一般的视频封装格式比如MP4等,如果是本地播放的媒体文件就不需要解协议;然后对视频媒体文件进行解封装&#x…

【杂谈】并发和并行、同步和异步、阻塞和非阻塞、IO模型

文章目录并行和并发\color{#ef246f}{并行和并发}并行和并发并行并发同步和异步\color{#1be34f}{同步和异步}同步和异步同步异步阻塞和非阻塞\color{#0636e5}{阻塞和非阻塞}阻塞和非阻塞阻塞非阻塞IO模型\color{#3ae2ea}{IO模型}IO模型阻塞IO非阻塞IO多路复用IO异步IOpython中异…