全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-09-26_全网最细使用Vite搭建一个组件库

您的位置:首页 >> 新闻 >> 行业资讯

全网最细使用Vite搭建一个组件库 点击关注公众号,“技术干货”及时达!准备工作先使用vite 搭建基础版本脚手架这里不做讲解、由于vite初始化什么都没有安装、我采用了自己改造过的脚手架 详情见GitHub 内置vue-router、commitlint、stylelint、eslint、prettier、unplugin-vue-components、unplugin-auto-import、lint-staged、sentry、pinia、husky...基本上可以满足团队日常开发需求。 ??言归正传、生成目录大概是这样的 ├── README.md├── commitlint.config.cjs├── index.html├── package.json├── pnpm-lock.yaml├── public│ ├── version.txt│ └── vite.svg├── src│ ├── App.vue│ ├── api│ │ └── index.ts│ ├── assets│ ├── auto-imports.d.ts│ ├── components│ ├── components.d.ts│ ├── global.d.ts│ ├── hooks│ ├── intercept.ts│ ├── main.ts│ ├── router│ ├── store│ ├── utils│ ├── views│ ├── vite-env.d.ts│ └── workers│ ├── versionCheckWorker.ts│ └── worker.ts├── tsconfig.json├── tsconfig.node.json└── vite.config.ts一系列的修改操作 修改src为packages,删除views目录修改alias把所有和src相关的别名路径修改为components、修改目录为vite.config.ts、tsconfig.json// vite.config.ts alias: [ { find: "@", replacement: resolve(__dirname, "../packages"), }, ],// tsconfig.json{... "paths": { "@/*": [ "packages/*" ], },...}删除不需要用到的文件夹 store...修改index.html中script标签中src路径为/packages/main.tspackages 下新建文件夹theme-chalk 后续用来存放样式修改后的目录结构 ├── README.md├── commitlint.config.cjs├── index.html├── package.json├── pnpm-lock.yaml├── public│ ├── version.txt│ └── vite.svg├── packages│ ├── App.vue│ ├── api│ ├── assets│ ├── auto-imports.d.ts│ ├── components│ ├── components.d.ts│ ├── global.d.ts│ ├── hooks│ ├── intercept.ts│ ├── main.ts│ ├── router│ ├── store│ ├── utils│ └── vite-env.d.ts├── tsconfig.json├── tsconfig.node.json└── vite.config.ts后续就可以在components文件夹下开发组件了,查看组件的话直接在router上配置路径即可 敲黑板:每个组件必须设置name,不然后续全局注册会有问题 components整体格式如下 ├── components ├── button │ ├──Button.vue │ └──index.ts └──index.ts相关代码如下 !-- Button.vue --template div class="bq-button" span-测试按钮-6/span /div/template script setup lang="ts"defineOptions({ name: "BqButton",});/script style lang="scss" scoped@import "@theme-chalk/button.scss";/style// index.tsimport Button from "./Button.vue";import { withInstall } from "../../utils/tool";export const BqButton = withInstall(Button);export default BqButton;withInstall相关方法如下、主要是为了全局注册 import type { App } from "vue";export const withInstall = T extends Component(comp: T) = { (comp as Recordstring, unknown).install = (app: App) = { const compName = comp.name; if (!compName) return; app.component(compName, comp); }; return comp;};// 最外层index.tsexport * from "./button";这时候我们的组件基本就写好了,查看组件只需要在router下配置路径即可 { path: "/", name: "button", meta: { title: "login", }, component: () = import(/* webpackChunkName: "button" */ "@/components/button/Button.vue"), },打包配置先给大家看配置、再给大家讲为什么 // vite.config.tsimport { defineConfig } from "vite";import vue from "@vitejs/plugin-vue";import { resolve } from "path";import { pluginsConfig, resolveConfig } from "./scripts/preview";import dts from "vite-plugin-dts";export default defineConfig(() = { return { build: { outDir: "build", cssCodeSplit: true, rollupOptions: { external: ["three", "@ant-design/icons-vue", "ant-design-vue", "unplugin-vue-components", "unplugin-auto-import", "vue"], output: [ { format: "es", entryFileNames: "[name].js", exports: "named", name: "BqDesign", dir: "./build/dist", }, { format: "es", entryFileNames: "[name].js", exports: "named", preserveModules: true, preserveModulesRoot: "packages", dir: "./build/es", }, { format: "cjs", entryFileNames: "[name].js", exports: "named", preserveModules: true, preserveModulesRoot: "packages", dir: "./build/lib", }, ], }, lib: { entry: resolve(__dirname, "./packages/index.ts"), name: "BqDesign", fileName: (format) = `bq-design.${format}.js`, formats: ["es", "cjs"], }, }, plugins: [ vue(), dts({ tsconfigPath: "./tsconfig.prod.json", outDir: "build/lib", }), dts({ tsconfigPath: "./tsconfig.prod.json", outDir: "build/es", }), ...pluginsConfig, ], resolve: resolveConfig, };}); 一点一点给大家捋一下为什么这么写 1、为什么output需要这样配置首先按照官网给的示例配置并执行 image.png打包后,有问题吗?没问题。但就是有点奇怪,因为我们打包后结构是这样的 └── dist ├── index.js └── style.css毕竟我们都是见过世面的??,为什么我们打包出来的和ant-design-vue、ElementPlus差距这么大, 其实小编在做这个事情的时候也看了这些优秀的开源组件库、毕竟学习的过程就是先模仿后创造 image.png大概看了一下 ElementPlus 是基于vite开发的,ant-design-vue还是webpack、那我们先看一下ElementPlus打包后的结构大概如下 └── build ├── dist ├── es ├── lib ├── README.md └── package.json很明显他输出了三个包(说明我们在output中也需要配置3个输出文件)、首先es文件夹用来兼容esm语法、lib文件夹兼容commentJs、dist也是esm语法他的css是打包在一个文件里的主要是为了全局引入css,配置好后大概是这个样子 output: [ { format: "es", entryFileNames: "[name].js", dir: "./build/dist", }, { format: "es", entryFileNames: "[name].js", dir: "./build/es", }, { format: "cjs", entryFileNames: "[name].js", dir: "./build/lib", }, ],之后我们执行打包脚步 pnpm run build 不报错的情况下打包出来应该已经是有三个文件了,但好像js和css还是在一起,怎么办?当然是看文档了?? image.pngimage.png原来如此、配置后执行打包命令,果然没问题 2、为什么cssCodeSplit是要改为true?因为在vite在lib模式下cssCodeSplit默认是false,其实官方有说明,可只在英文文档做了说明?? image.png没注意到的打包后所有组件css都在一个文件、后续就没有办法实现我们的按需引入了 3、如何打包出ts类型标注使用pnpm下载 vite-plugin-dts 该插件 pnpm add vite-plugin-dts -D 由于我们在lib和es库里都需要打包ts,所以需要配置两个dts,代码如下 dts({ tsconfigPath: "./tsconfig.prod.json", outDir: "build/lib", }), dts({ tsconfigPath: "./tsconfig.prod.json", outDir: "build/es", }),tsconfigPath,需要单独引入一个新的tsconfig配置、主要是因为我们打包的include和exclude配置和实际开发中还是有一定区别。并且include配置有问题会导致打包出的类型没有放在实际文件夹下。 新建了一个tsconfig.prod.json文件,代码如下 { "extends": "./tsconfig.json", "include": [ "packages/**/*.vue", "packages/**/*.d.ts", "packages/**/*.ts", ], "exclude": [ "./packages/main.ts", "node_modules", "./packages/router/*" ]}走到这里其实我们的组件已经小有所成了 开发文档一个好的组件离不开一个优秀的文档、这里我推荐大家使用VitePress,相对于市面上其他的文档生成工具VitePress拥有着强大的生态环境和相对稳定的版本,文档地址,根据文档操作,之后会在最外层目录下生成一个docs文件,里面就可以快乐的写我们的文档了,这里就不做演示了。 image.png关于 unplugin-vue-components 自动引入const BqDesignResolver = () = { return { type: "component" as const, resolve: (name) = { if (name.startsWith("Bq")) { const pathName = name.slice(2).toLowerCase(); return { importName: name, from: "bq-design", path: `bq-design/es/components/${pathName}/index.js`, sideEffects: `bq-design/es/components/${pathName}/${name.slice(2)}.css`, }; } }, };};更改名称为自己组件库即可 手动导入组件在vite中严格意义上是不需要手动导入,因为Vite提供了基于 ES Module 的开箱即用的Tree Shaking 功能,但有一种情况就是我开发的组件库引入了第三方包,比如threeJs,但在实际运用中,我只引用了我的Button按钮,会报错,因为我们的导出模块是有关联的,实际这么引用 上述情况使用Vite一定要在optimizeDeps.exclude 添加相应的包如bq-design,因为预加载发现缺少依赖会报错 import {Button} from 'bq-design'开发环境下是会导出全部的bq-design(生产环境并不会哦),默认情况按需引入需要这样导入 import BqButton from "bq-design/es/components/button";但这样还存在着无法引入样式的问题,所以我们需要自己开发一个vite插件进行转换,代码如下 export default function importPlugin() { const regStr = /(?!\/\/.*|\/\*[\s\S]*?\*\/\s*)import\s*{\s*([^{}]+)\s*}\s*from\s*['"]bq-design['"]/g; return { name: "vite-plugin-import", enforce: "pre", transform: (code: string, id: string) = { if (id.endsWith(".vue")) { const str = code.replaceAll(regStr, (match, imports) = { const list = imports.split(","); const newPath: string[] = []; list.forEach((item: string) = { item = item.trim(); const name = item.slice(2).charAt(0).toLowerCase() + item.slice(3); const str = `import ${item.trim()} from 'bq-design/es/components/${name.trim()}'; import 'bq-design/es/components/${name.trim()}/${item.trim().slice(2)}.css'`; newPath.push(str); }); return newPath.join(";"); }); return str; } return code; }, };}Webpack用户可以使用 babel-plugin-import进行处理同样这也是ant-design-vue的处理方式 本地测试组件库推荐使用 yalc这是小编自己搭建的组件库地址 https://biuat.ibaiqiu.com/bq-design/ 相关github地址 https://github.com/Js-Man-H5/bq-deign 点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2022-07-12_从无印良品历年企业广告,看一个品牌的人文之旅 下一篇:2025-09-30_节前重磅:开源旗舰模型新SOTA,智谱GLM-4.6问世

TAG标签:

18
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价