热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用vite搭建组件库、全量打包组件库的实践过程

目录1.根据vite文档,新建项目,安装elementplus、vue-router2.在componentsmenusrc目录下,新

目录

1. 根据 vite 文档,新建项目,安装 elementplus、vue-router

2. 在 components/menu/src 目录下,新建 index.vue

3. 在 components/menu 目录下,新建 index.ts

4. 在 components 目录下,新建 index.ts

5. 在 main.ts 中使用刚刚导出的全量组件

6. 在 views 目录下使用组件

7. 在 src 目录下新建 packages 目录,并添加内容

8. 新建 command/build.js 实现全量打包命令配置

9. 修改 package.json ,执行组件库全量打包命令

10. 在项目中使用上面打包的组件库




1. 根据 vite 文档,新建项目,安装 elementplus、vue-router

截止 2022-03-24,最新版的 element-plus,会自动安装 elementplus 的 icons 模块


yarn create vite my-vue-app --template vue 

yarn add element-plus

yarn add vue-router



2. 在 components/menu/src 目录下,新建 index.vue

作用:封装菜单组件(使用 elementplus 对 导航组件 进行二次封装)



3. 在 components/menu 目录下,新建 index.ts

作用:注册全局组件,实现按需引入(让组件可以通过 app.use() 的形式使用)

注意:引入组件时,一定要加上 .vue 后缀;如果不加,会导致打包后生成的 .es.js 无法在项目中使用

import { App } from 'vue'
import menu from './src/index.vue'// 让组件可以通过 app.use() 的形式使用
export default {install(app: App) {app.component('l-menu', menu)}
}


4. 在 components 目录下,新建 index.ts

作用:注册全局组件,实现全局引入(让组件可以通过 app.use() 的形式使用);最终在 views 下使用的组件,其实是这个 index.ts 中注册的组件;

注意:这里引入的是 组件目录下的 index.ts 文件,不是 index.vue 组件

import { App } from 'vue'
import menu from './menu'// 最终在 views 下使用的组件,其实是这个 index.ts 中注册的组件
const compOnents= [menu,
]export default {/*** 让组件可以通过 app.use() 的形式使用* @param app */install(app: App) {components.map(item => {app.use(item)})}
}


5. 在 main.ts 中使用刚刚导出的全量组件

import { createApp } from 'vue'
import App from './App.vue'// 引入 路由
import router from './router/index'// 引入 elementplus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 引入 element-plus Icon
import * as Icons from '@element-plus/icons-vue'import { toLine } from './utils/index'import lBusinessComponents from './components/index'
// import lBusinessComponents from '../lib/l-business-components.es.js'
// import '../lib/style.css'const app = createApp(App)// 全局注册图标 牺牲一点性能
for (let i in Icons) {/*** console.log((Icons as any)[i])* 默认情况下,会打印出 Object,使用驼峰命名,如: "Switch"* 希望转换成 el-icon-xxx 的形式,就需要用新的方式全局注册组件*/// 注册全部 elementplus Icon 组件(使用方法:el-icon-xxx)app.component(`el-icon-${toLine(i)}`, (Icons as any)[i])
}app.use(router)
app.use(ElementPlus)
app.use(lBusinessComponents)
app.mount('#app')


6. 在 views 目录下使用组件

如果组件可以正常的渲染出来,则证明组件已经实现了全局注册,接下来可以进行打包操作啦


7. 在 src 目录下新建 packages 目录,并添加内容

下面每一步都很重要哦 ❗ ❗ ❗

把 components 目录下的所有内容,复制到 packages 目录下;

同时还要复制 hooks、styles、utils 等文件夹 到 packages 目录下,因为组件用到了这些内容,他们需要一起被打包;

修改 packages/index.ts,引入需要的样式文件、工具文件(不是组件特有的,是全局存放的,这一步非常容易忘);

我在下面的文件中,引入了两个组件,一个是用 .tsx 写的,一个是 .vue 写的,这两个组件是可以写在一个文件夹下的,并且同时在 index.ts 中进行导出;

这里需要注意的是,我还复制了 src 目录下的 vue 声明文件,因为我在任何 index.ts 中导入 vue 文件的时候,路径都爆红了,说找不到 vue 模块;

我最初以为是缺少 vue ts 声明文件,但是加上了这个声明文件路径报错依然存在;

我可以保证我已经在 vue.config.js 和 vite.config.js 和 tsconfig.js 中添加过路径相关的配置了;

后来才明白这个报错可以无视,不会影响打包效果;如果影响了,那就根本无法进行打包,所以这里先跳过吧 ovo;

import { App } from 'vue'import menu from './menu/src/index.vue'
import lInfiniteMenu from './menu/src/menu.tsx'// 引入样式
import './styles/common.scss'
import './styles/element-plus.scss'// 最终在 views 下使用的组件,其实是这个 index.ts 中注册的组件
const compOnents= [menu,lInfiniteMenu,
]/*** 让组件可以通过 app.use() 的形式使用* @param app */
const install = (app: App): void => {app.component('l-menu', menu);app.component('l-infinite-menu', lInfiniteMenu);// components.forEach((component: any) => {// app.component(component.name, component);// });
};export {menu,lInfiniteMenu,
}export default {install
}


8. 新建 command/build.js 实现全量打包命令配置

添加此文件时,我最初使用 require 引入 path 模块,打包的时候就报错了,说 es6 不能使用 require;

经过一番百度,我决定通过 module 模块中的 createRequire 方法,来使用 es6之前的 require;

再有一个坑:我在定义导出路径的时候,写成 src/packages,就会打包报错,写成 packages 就正常了,还没进行打印,不过如果路径报错的话,可以先尝试修改导出位置,在测试打包功能;

/*** 实现组件全局(全量)打包* @description 因为通过 node 打包,所以采用 CommonJS 规范,也就是 require*/import { createRequire } from 'module';
import path from "path"const requireds = createRequire(import.meta.url);
const __dirname = path.resolve();// vite 打包需要的配置
const { defineConfig, build } = requireds('vite');// vite 插件
const vue = requireds('@vitejs/plugin-vue');
const vueJsx = requireds('@vitejs/plugin-vue-jsx');// 添加打包入口文件夹 packages(需要手动创建)
const entryDir = path.resolve(__dirname, 'packages');
// 添加出口文件夹 lib(不需要手动创建,会自动生成)
const outDir = path.resolve(__dirname, 'lib');// vite 配置
const baseCOnfig= defineConfig({configFile: false,publicDir: false,plugins: [vue(), vueJsx()]
});// rollup 配置(vite 基于 rollup 打包)
const rollupOptiOns= {// 这两个库不需要打包external: ['vue', 'vue-router'],output: {globals: {vue: 'Vue'}}
};/*** 全量打包构建的方法*/
const buildAll = async () => {await build({...baseConfig,build: {rollupOptions,lib: {// 入口entry: path.resolve(entryDir, 'index.ts'),// 组件库名字name: 'l-business-components',fileName: 'l-business-components',// 输出格式formats: ['es', 'umd']},outDir}})
};/*** 打包成库*/
const buildLib = async () => {await buildAll();
};buildLib();


9. 修改 package.json ,执行组件库全量打包命令

在 package.json 中添加两行命令

    "build:components": "node --trace-warnings ./command/build.js",
    "lib": "npm run build:components"

"scripts": {"dev": "vite","build": "vue-tsc --noEmit && vite build","preview": "vite preview","build:components": "node --trace-warnings ./command/build.js","lib": "npm run build:components"},

保存后,执行组件库全量打包命令,也就是 yarn lib,控制台输出如下:

香喷喷的组件库全量打包成功啦,生成了下面的文件


10. 在项目中使用上面打包的组件库

需要注意的是,此时组件库是全量打包,打出来的文件包含了全部组件,而不是部分组件,也就是说,还没有实现按需引入组件的功能

在 main.ts 中,引入刚刚生成的 .es.js 文件,并全局注册组件库

路径会爆红,但是不要在意,会成功的

// import LBusinessComponents from './components/index'// 使用打包后的组件库(注意此处不是按需引入,是全局引入)
import LBusinessComponents from '../lib/l-business-components.es.js'
import '../lib/style.css'app.use(LBusinessComponents)

这样,原来在 views 目录下使用的 组件就可以继续生效了

最开始使用打包文件的时候,报错 component render function not find,错误原因有两点:


  • 配置 packages 和 components 目录下的 index.ts 时,导入组件全都没有加 .vue 文件结尾
  • 封装组件的时候,使用了 setup 语法糖

按道理讲语法糖不会影响组件库打包的,目前还没研究出 为什么使用语法糖编写组件时,打包之后的组件库就渲染不出来了,components 下的组件还可以正常渲染...

希望有小伙伴可以帮忙指正!


推荐阅读
  • vue使用
    关键词: ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文讨论了为什么在main.js中写import不会全局生效的问题,并提供了解决方案。在每一个vue文件中都需要写import语句才能使其生效,而在main.js中写import语句则不会全局生效。本文还介绍了使用Swal和sweetalert2库的示例。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
  • Vue项目之ElementUI(Breadcrumb)动态面包屑效果
    效果面包屑作用面包屑应该是我们在项目中经常使用的一个功能,一般情况下它用来表示我们当前所处的站点位置,也可以帮助我们能够更快的回到上个层级原始方式最笨的 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
每天进步一点就好
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有