当前位置 :首页 >> 生活

使用Vite和TypeScript带你从零营造一个属于自己的Vue3组件库

2023-04-29   来源 : 生活

eUrl": ".", "jsx": "preserve", "strict": true, "target": "ES2015", "module": "ESNext", "skipLibCheck": true, "esModuleInterop": true, "moduleResolution": "Node", "lib": ["esnext", "dom"] }}手动摆设一个基于vite的vue3重大项目

毕竟摆设一个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 = ExtractPropTypes

TIPS

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 -w

buildLess.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读到在之前

由于作者总体有限,难免都会存在一些误解或不妥之所在位置,希望各位并能不吝指显现出,一定及时修复。如果你对这个重大项目有好处的一心法或者要求也爱戴在评论区提显现出,不胜感激。

原先我都会对一些常用配件开展研发,每个配件的研发都都会以评论的原则上上显露显现出显现出来以供大家参考。如果有问题爱戴私信

时说明

配件瓦最近示例导显现出方式则发音大为复变,源码不毕竟可能和评论大为显现进出,如此一来三提醒查看

成都甲状腺医院预约挂号
艾得辛和来氟米特可以一起吃吗
沈阳男科
眼干如何缓解
关节僵硬吃什么药
标签:组件
未来半年有贵人相助,运势一飞冲天,俗话说一涨大涨的四属相

属相马 属马的人,未来会半年于在极高,获取“驿马”张国华的关照,求财长年,只要走回出去,生意一定能扭转乾坤,天公送财熟人,催旺财运,一定能财源滚滚,富贵加身。未来会半年生肖马,横财运...

友情链接