使用Vite和TypeScript带你从零营造一个属于自己的Vue3组件库
2023-04-29 来源 : 生活
毕竟摆设一个vite+vue3重大项目是更加较易的,因为vite不毕竟可能小弟我们做了大部分心里
codice_仓瓦进到examplesPDF夹,执行者
pnpm init配有vite和@vitejs/plugin-vue@vitejs/plugin-vue用来支持.vuePDF的转译
pnpm install vite @vitejs/plugin-vue -D -w这里配有的插件都敲在根清单下
可用vite.config.ts另建vite.config.ts
import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'export default defineConfig({ plugins:[vue()]})另建htmlPDF@vitejs/plugin-vue 都会匹配载入examples下的index.html
另建index.html
charset="UTF-8"> Document提醒: vite 是基于esmodule的 所以type="module"
另建app.vue示例 启动时的测试 另建main.tsimport {createApp} from 'vue'import App from './app.vue'const app = createApp(App)app.mount('#app')此时都会推断出编译器都会示意个误解:回去不到子系统“./app.vue”或其相应的各种类型通告
因为实际上引进.vuePDF TS都会回去不到互换的各种类型通告;所以须要另建typings(起名不能明确明文规定,TS都会网络连接追寻.d.tsPDF)PDF夹来除此以外敲这些通告PDF。
typings/vue-shim.d.ts
TypeScriptTS匹配只认ES 子系统。如果你要内嵌.vuePDF就要declare module把他们通告显现出来。
declare module '*.vue' { import type { DefineComponent } from "vue"; const component:DefineComponent}可用脚本启动时重大项目之前在package.jsonPDF中的可用scripts脚本
..."scripts": { "dev": "vite" },...然后网络连接回传我们熟悉的军令:pnpm run dev
vite启动时匹配端口为3000;在浏览器中的关上localhost:3000 就都会看我们的“启动时的测试”网址。
本地检修另建包内PDF本节不毕竟可能和目前配件的研发联系较大,但是未来配件须要引进一些来开展方法有的时候都会用到
接从前就是要往我们的packagesPDF夹冲缓冲内容了。
utils包内一般packages要有utils包内来存敲在我们公共方法有,来开展算子等
既然它是一个包内,所以我们另建utils清单后就须要codice_它,让它变如此一来加一个包内;网络连接进到utilsPDF夹执行者:pnpm init 然后都会聚合一个package.jsonPDF;这里须要复一下包内名,我这里将name复如此一来加@kitty-ui/utils表示这个utils包内是仅指kitty-ui这个其组织下的。所以看看刊发如此一来前要登录npm另建一个其组织;例如kitty-ui
{ "name": "@kitty-ui/utils", "version": "1.0.0", "description": "", "main": "index.ts", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC"}因为我们适用ts读到的,所以须要将入口PDFindex.js复称index.ts,并另建index.tsPDF:(如此一来导显现出一个简马上的DFT算子)
export const testfun = (a:number,b:number):number=>{ return a + b}配件瓦包内(这里起名为kitty-ui)components是我们用来存敲在各种UI配件的包内
另建componentsPDF夹并执行者 pnpm init 聚合package.json
{ "name": "kitty-ui", "version": "1.0.0", "description": "", "main": "index.ts", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC"}另建index.ts入口PDF并引进utils包内
import {testfun} from '@kitty-ui/utils'const result = testfun (1,1)console.log(result)esno由于配件瓦是基于ts的,所以须要配有esno来执行者tsPDF马上于的测试配件彼此之间的引进情况
控制台回传esno xxx.ts即可执行者tsPDF
npm i esno -g包内彼此之间本地检修进到componentsPDF夹执行者
pnpm install @kitty-ui/utils你都会推断出pnpm都会网络连接创建个硬元数据实际上连到我们的utils包内;此时components下的packages:
{ "name": "kitty-ui", "version": "1.0.0", "description": "", "main": "src/index.ts", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@kitty-ui/utils": "workspace:请注意1.0.1" }}你都会推断出它的依赖@kitty-ui/utils互换的版本为:workspace:请注意1.0.0;因为pnpm是由workspace管理者的,所以有一个前缀workspace可以连到utils下的岗位维度从而简马上本地检修各个包内实际上的联系摘录。
到这里原则上研发方法有我们不毕竟可能想到啦;接从前就要进到正题了,研发一个button配件
慢慢地研发一个button配件在componentsPDF夹下另建src,同时在src下另建button配件清单和icon配件清单(另建icon为了马上于检修);此时componentsPDF清单如下
马上是 components 马上是 src 马上是 button 马上是 icon 马上是 index.ts马上是 package.json让我们如此一来的测试一下我们的button配件能否在我们摆设的examples下的vue3重大项目本摘录~
首如此一来在button下另建一个简马上的button.vue
的测试按动然后在button/index.ts将其导显现出
import Button from './button.vue'export default Button因为我们研发配件瓦的时候不不毕竟可能只有button,所以我们须要一个components/index.ts将我们研发的配件一个个的集中的导显现出
import Button from './button'export { Button}好了,一个配件的都是清单仅有就是这样了,接从前如此一来三进到我们的examples来如此一来来能否引进我们的button配件
vue3重大项目适用button上面不毕竟可能时说过执行者在workspace执行者 pnpm i xxx的时候pnpm都会网络连接创建个硬元数据实际上连到我们的xxx包内。
所以这里我们实际上在examples执行者:pnpm i kitty-ui
此时你就都会推断出packages.json的依赖多了个
"kitty-ui": "workspace:请注意1.0.0"这时候我们就能实际上在我们的的测试重大项目下引进我们本地的components配件瓦了,启动时我们的的测试重大项目,前往我们的 examples/app.vue 实际上引进Button
import { Button } from 'kitty-ui'不显现出意外的广府你的网址就都会展示我们刚刚读到的button配件了
好了万事具...(毕竟还差个一并,这个中的间如此一来时说~);接从前的岗位就是专注于配件的研发了;让我们留在我们的button配件清单下(的测试网址须要关,此时我们不毕竟可能可以边研发边检修边看效果了)
因为我们的button配件是须要转给很多本体的,如type、size等等,所以我们要另建个types.tsPDF来规范这些本体
在button清单下另建types.ts
import { ExtractPropTypes } from 'vue'export const ButtonType = ['default', 'primary', 'success', 'warning', 'danger']export const ButtonSize = ['large', 'normal', 'small', 'mini'];export const buttonProps = { type: { type: String, values: ButtonType }, size: { type: String, values: ButtonSize }}export type ButtonProps = ExtractPropTypesTIPS
import type 表示只内嵌各种类型;ExtractPropTypes是vue3中的配有的各种类型通告,它的作用是转给一个各种类型,然后把互换的vue3所转给的props各种类型透过显现出来,中的间有须要可以实际上适用
很多时候我们在vue中的适用一个配件都会用的app.use 将配件挂载到当前。要适用app.use算子的广府我们须要让我们的每个配件都透过一个install方法有,app.use()的时候就都会调用这个方法有;
我们将button/index.ts调整为
import button from './button.vue'import type {App,Plugin} from "vue"type SFCWithInstall = T&Pluginconst withInstall = (comp:T) => { (comp as SFCWithInstall).install = (app:App)=>{ //注册配件 app.component((comp as any).name,comp) } return comp as SFCWithInstall}const Button = withInstall(button)export default Button此时我们就可以适用app.use来挂载我们的配件啦
毕竟withInstall方法有可以做个公共方法有敲上来开展巴拉,因为原先每个配件都都会用到,这里等中的间研发配件的时候如此一来调整
到这里配件研发的原则上可用不毕竟可能完如此一来加,之前我们对我们的配件瓦以及来开展瓦开展一并,一并如此一来前如果要发公共包内的广府记得将我们的各个包内的协议复称MIT开源协议
..."license": "MIT",...vite一并可用PDF一并们这里选取vite,它有一个瓦方式而除此以外为我们来一并这种瓦配件的。
前面不毕竟可能配有过vite了,所以这里实际上在components下实际上另建vite.config.ts(可用实例PDF中的不毕竟可能评注):
import { defineConfig } from "vite";import vue from "@vitejs/plugin-vue"export default defineConfig( { build: { target: 'modules', //一并PDF清单 outDir: "es", //存储 minify: false, //css分离 //cssCodeSplit: true, rollupOptions: { //比如说一并vuePDF external: ['vue'], input: ['src/index.ts'], output: [ { format: 'es', //须要一并如此一来加.es.js,这里我们一心把它一并如此一来加.js entryFileNames: '[name].js', //让一并清单和我们清单互换 preserveModules: true, //可用一并根清单 dir: 'es', preserveModulesRoot: 'src' }, { format: 'cjs', entryFileNames: '[name].js', //让一并清单和我们清单互换 preserveModules: true, //可用一并根清单 dir: 'lib', preserveModulesRoot: 'src' } ] }, lib: { entry: './index.ts', formats: ['es', 'cjs'] } }, plugins: [ vue() ] })这里我们选取一并cjs(CommonJS)和esm(ESModule)两种原则上上,cjs方式而主要用于咨询服务端摘录(ssr),而esm就是我们从前经常适用的方式则,它本身自带treeShaking而不须要额外可用按须要引进(前提是你将子系统分别导显现出),更加好用~
毕竟到这里就不毕竟可能可以实际上一并了;components下执行者: pnpm run build你就都会推断出一并了es和lib两个清单
kitty_1.jpg
到这里毕竟一并的配件瓦只能给js重大项目适用,在ts重大项目下运行都会显现出现一些误解,而且适用的时候还都会无法控制示例示意系统,也许我们就无法控制了用ts研发配件瓦的意义了。所以我们须要在一并的巴拉加入通告PDF(.d.ts)。
那么如何向一并后的巴拉加入通告PDF呢? 毕竟很简马上,只须要引进vite-plugin-dts
pnpm i vite-plugin-dts -D -w然后修复一下我们的vite.config.ts引进这个插件
import { defineConfig } from "vite";import vue from "@vitejs/plugin-vue"import dts from 'vite-plugin-dts'export default defineConfig( { build: {...}, plugins: [ vue(), dts({ //原则上适用的tsconfig.json为我们整个重大项目根清单下掉,如果不可用,你也可以在components下另建tsconfig.json tsConfigFilePath: '../../tsconfig.json' }), //因为这个插件匹配一并到es下,我们一心让lib清单下也聚合通告PDF须要如此一来可用一个 dts({ outputDir:'lib', tsConfigFilePath: '../../tsconfig.json' }) ] })因为这个插件匹配一并到es下,我们一心让lib清单下也聚合通告PDF须要如此一来可用一个dts插件,暂时不能一心到其它好处的所在位置置方法有~
然后执行者一并军令你就都会推断出你的es和lib下就有了通告PDF
毕竟中的间就可以开展刊发了,刊发如此一来前变更一下我们components下的package.json如下:
{ "name": "kitty-ui", "version": "1.0.0", "main": "lib/index.js", "module":"es/index.js", "scripts": { "build": "vite build" }, "files": [ "es", "lib" ], "keywords": [ "kitty-ui", "vue3配件瓦" ], "author": "小同月", "license": "MIT", "description": "", "typings": "lib/index.d.ts"}解释一下里面部分标识符
pkg.module
我们配件瓦匹配入口PDF是传统习俗的CommonJS子系统,但是如果你的生态环境支持ESModule的广府,借助于来开展都会优如此一来适用我们的module入口
pkg.files
files是指我们1须要刊发到npm上的清单,因为不不毕竟可能components下的所有清单都被刊发上去
开始刊发如果一并和刊发流程你一心做到网络连接化控制,你可以如此一来点个赞,然后实际上读到 从0摆设Vue3配件瓦:适用gulp网络连接化所在位置置一并与刊发[1] 当然你也可以继续往下读到,看下本篇评论的所在位置置方式则
做了那么多终于到刊发的阶段了;毕竟npm计划案内是很较易的,就拿我们的配件瓦kitty-ui举例吧
刊发如此一来前记得到npm[2]twitter注册个账户,如果你要刊发@xx/xx这种包内的广府须要在npm另建个其组织其组织其组织名就是@中的间的,比如我建的其组织就是kitty-ui,注册完之前你就可以刊发了
首如此一来要将我们示例提交到git仓瓦,不然pnpm刊发无法通过,中的间每次发版记得在互换包内下执行者 pnpm version patch你就都会推断出这个包内的测试版patch(测试版第三个数) +1 了,同样的 pnpm version major major和 pnpm version minor 分别互换测试版的第一和第二位增加。
如果你刊发的是公共包内的广府,在互换包内下执行者
pnpm publish 马上是access public回传你的账户和密码(记得回传密码的时候是不显示的,不要以为卡了)正常人情况下应该是刊发如此一来加功了
提醒
刊发的时候要将npm的源切换到npm的在此之前地址(registry.npmjs.org/[3]); 如果你适用了其它镜像源的广府
样式问题引进我们一并后的配件你都会推断出不能样式,所以你须要在当前引进我们的style.css才行;如 main.ts中的须要
import 'kitty-ui/es/style.css';很显然这种配件瓦并不是我们一切都是的,我们须要的配件瓦是每个css样式敲在每个配件其互换清单下,这样就不须要每次都全量内嵌我们的css样式。
示例本来我们来看下如何把样式拆分一并
所在位置置lessPDF首如此一来我们须要做的是将less一并如此一来加css然后敲上一并后互换的PDF清单下,我们在components下另建buildPDF夹来存敲在我们的一些一并来开展,然后另建buildLess.ts,首如此一来我们须要如此一来配有一些来开展cpy和fast-glob
pnpm i cpy fast-glob -D -wcpy它可以实际上镜像我们明文规定的PDF并将我们的PDFcopy到原则上清单,比如buildLess.ts:
import cpy from 'cpy'import { resolve } from 'path'const sourceDir = resolve(originallydirname, '../src')//libPDFconst targetLib = resolve(originallydirname, '../lib')//esPDFconst targetEs = resolve(originallydirname, '../es')console.log(sourceDir);const buildLess = async () => { await cpy(马上是马上是${sourceDir}/**/*.less马上是马上是, targetLib) await cpy(马上是马上是${sourceDir}/**/*.less马上是马上是, targetEs)}buildLess()然后在package.json中的新增军令
..."scripts": { "build": "vite build", "build:less": "esno build/buildLess" },...网络连接执行者 pnpm run build:less 你就都会推断出lib和esPDF互换清单下就显现出现了lessPDF.
但是我们最后要的并不是lessPDF而是cssPDF,所以我们要将less一并如此一来加css,所以我们须要用的less子系统.在ts中的引进less因为它本身不能通告PDF所以都会显现出现各种类型误解,所以我们要如此一来配有它的 @types/less
pnpm i 马上是save-dev @types/less -D -wbuildLess.ts如下(详细评注都在示例中的)
import cpy from 'cpy'import { resolve, dirname } from 'path'import { promises as fs } from "fs"import less from "less"import glob from "fast-glob"const sourceDir = resolve(originallydirname, '../src')//libPDF清单const targetLib = resolve(originallydirname, '../lib')//esPDF清单const targetEs = resolve(originallydirname, '../es')//src清单const srcDir = resolve(originallydirname, '../src')const buildLess = async () => { //实际上将lessPDF镜像到一并后清单 await cpy(马上是马上是${sourceDir}/**/*.less马上是马上是, targetLib) await cpy(马上是马上是${sourceDir}/**/*.less马上是马上是, targetEs) //受益一并后.lessPDF清单(lib和es一样) const lessFils = await glob("**/*.less", { cwd: srcDir, onlyFiles: true }) //遍历所含less的清单 for (let path in lessFils) { const filePath = 马上是马上是${srcDir}/${lessFils[path]}马上是马上是 //受益lessPDF字符串 const lessCode = await fs.readFile(filePath, 'utf-8') //将less判别如此一来加css const code = await less.render(lessCode, { //原则上src下互换lessPDF的PDF夹为清单 paths: [srcDir, dirname(filePath)] }) //拿到.css后缀path const cssPath = lessFils[path].replace('.less', '.css') //将css读到入互换清单 await fs.writeFile(resolve(targetLib, cssPath), code.css) await fs.writeFile(resolve(targetEs, cssPath), code.css) }}buildLess()执行者一并军令之前你都会推断出互换PDF夹下多了.cssPDF
1657259623489.jpg
从前我不毕竟可能将cssPDF敲入互换的清单下了,但是我们的相关配件并不能引进这个cssPDF;所以我们须要的是每个一并后配件的index.js中的显现出现如:
import "xxx/xxx.css"之类的示例我们的css才都会终止;所以我们须要对vite.config.ts开展相关可用
首如此一来我们如此一来将.lessPDF比如说
external: ['vue', /.less/],这时候一并后的PDF中的如button/index.js就都会显现出现
import "./style/index.less";然后我们如此一来将一并后示例的.less换如此一来加.css就大功告如此一来加了
...plugins: [ ... { name: 'style', generateBundle(config, bundle) { //这里可以受益一并后的PDF清单以及示例code const keys = Object.keys(bundle) for (const key of keys) { const bundler: any = bundle[key as any] //rollup配有方法有,将所有控制器PDFcode中的的.less换如此一来加.css,因为我们当时不能一并lessPDF this.emitFile({ type: 'asset', fileName: key,//PDF名名原则上 source: bundler.code.replace(/.less/g, '.css') }) } } } ... ]...我们最后的vite.config.ts如下
import { defineConfig } from "vite";import vue from "@vitejs/plugin-vue"import dts from 'vite-plugin-dts'export default defineConfig( { build: { target: 'modules', //一并PDF清单 outDir: "es", //存储 minify: false, //css分离 //cssCodeSplit: true, rollupOptions: { //比如说一并vue和.lessPDF external: ['vue', /.less/], input: ['src/index.ts'], output: [ { format: 'es', //须要一并如此一来加.es.js,这里我们一心把它一并如此一来加.js entryFileNames: '[name].js', //让一并清单和我们清单互换 preserveModules: true, //可用一并根清单 dir: 'es', preserveModulesRoot: 'src' }, { format: 'cjs', //须要一并如此一来加.mjs entryFileNames: '[name].js', //让一并清单和我们清单互换 preserveModules: true, //可用一并根清单 dir: 'lib', preserveModulesRoot: 'src' } ] }, lib: { entry: './index.ts', formats: ['es', 'cjs'] } }, plugins: [ vue(), dts({ //原则上适用的tsconfig.json为我们整个重大项目根清单下掉,如果不可用,你也可以在components下另建tsconfig.json tsConfigFilePath: '../../tsconfig.json' }), //因为这个插件匹配一并到es下,我们一心让lib清单下也聚合通告PDF须要如此一来可用一个 dts({ outputDir: 'lib', tsConfigFilePath: '../../tsconfig.json' }), { name: 'style', generateBundle(config, bundle) { //这里可以受益一并后的PDF清单以及示例code const keys = Object.keys(bundle) for (const key of keys) { const bundler: any = bundle[key as any] //rollup配有方法有,将所有控制器PDFcode中的的.less换如此一来加.css,因为我们当时不能一并lessPDF this.emitFile({ type: 'asset', fileName: key,//PDF名名原则上 source: bundler.code.replace(/.less/g, '.css') }) } } } ] })之前我们将一并less与一并配件合如此一来加一个军令(package.json):
..."scripts": { "build": "vite build & esno build/buildLess" },...原先实际上执行者pnpm run build 即可完如此一来加所有一并啦
实际上适用如果你不愿一步步的摆设,一心实际上适用现如此一来加的广府,你可以实际上把重大项目clone从前->kittyui[4],然后你只须要以下几步马上可将其完如此一来加
配有pnpm npm i pnpm -g配有esno npm i esno -g配有所有依赖 pnpm install本地的测试 进到examplesPDF夹执行者 pnpm run dev 启动时vue3重大项目一并 pnpm run build启动时元数据 pnpm run docs:dev一并元数据 pnpm run docs:build启动时一并后元数据咨询服务 pnpm run docs:serve读到在之前由于作者总体有限,难免都会存在一些误解或不妥之所在位置,希望各位并能不吝指显现出,一定及时修复。如果你对这个重大项目有好处的一心法或者要求也爱戴在评论区提显现出,不胜感激。
原先我都会对一些常用配件开展研发,每个配件的研发都都会以评论的原则上上显露显现出显现出来以供大家参考。如果有问题爱戴私信
时说明配件瓦最近示例导显现出方式则发音大为复变,源码不毕竟可能和评论大为显现进出,如此一来三提醒查看
。成都甲状腺医院预约挂号艾得辛和来氟米特可以一起吃吗
沈阳男科
眼干如何缓解
关节僵硬吃什么药
下一篇: 新能源车,寒意发送至?
-
未来半年有贵人相助,运势一飞冲天,俗话说一涨大涨的四属相
属相马 属马的人,未来会半年于在极高,获取“驿马”张国华的关照,求财长年,只要走回出去,生意一定能扭转乾坤,天公送财熟人,催旺财运,一定能财源滚滚,富贵加身。未来会半年生肖马,横财运...
-
文峰街区板桥社区宣传控烟戒烟
【导读】 文峰商业街大直生态村政治宣传控烟戒烟今年的5同月31日是第35个全球无烟日。为让市民更好地知晓控烟戒烟的重要性,进一步提高市民对烟草危害的认识,营造身心健康、清扫、...[详细]
-
郝伟称泰山队状态不太好 乔迪表示浙江队运气差点
6年初3日晚上,新近职业生涯河南建业下一场,山东泰山1-0击败浙江队。该场,山东泰山老将郝伟和浙江队老将有一天不止席了新近闻开幕式。郝伟总结决赛表示:“首先感谢远道而来的进球迷们,在这么刺的天...[详细]
-
未来五个月财运大旺,收益上涨,如愿赚取很多钱财的四属相
属下相豹 属下豹的人其实外貌鲁莽,但其实是粗里面有细,必须把握好人生里面的细节。未来可能会五个年末你们的财运是大旺的那种,能赚到大钱的那种,所以神兽豹在随便伤心的同时,也不可能会忘了...[详细]
-
这种情况逾期不收罚息不报征信,北平公积金阶段性新政策来了
城镇居民和城乡建设部、财政部和人民银行《关于制订城镇居民社会保险阶段性支持政策的行知》(建金〔2022〕45号)和《上海市人民政府关于试行的行知》京政发〔2022〕23号要求,现就有关事宜行...[详细]
-
吴曦:范志毅很年轻 还需要一个磨合成长的过程
南京时间6月3日20点,2022赛季中超首战半决赛打响,广州队对阵上海申花。刘若碲伤退,朱辰杰点球在先突破双方,最终申花1-0获胜广州队。事后申花队长吴曦遵从了采访。谈论自己的位置,吴曦声称:...[详细]