如何封装Vue组件并上传到npm

前言

环境准备

1.注册npm账号:npm | Home (npmjs.com)

2.保证当前环境安装了vue、webpack、node,以下工作将在该环境下进行(没有的小伙伴自行百度安装哈~)

3.一下用到的环境版本

  • webpack:v5.1.4
  • node:v12.10.0
  • vue:v2.6.14

4.创建一个基于webpack的vue项目,这个项目将会是我们的组件项目了。

目录结构构建

在我们日常开发的项目中,通常的目录结构可能会像下图,我们一般会在根目录下的src/views中进行我们所有页面的开发,App.vue作为主页面引入。

但是呢,我们现在是想要进行组件开发,那么在项目的目录结构上可根据个人习惯进行一定的调整和更改如下:

 这里我说明一下主要的目录

  • components:存放你所需要开发的所有组件的目录
  • components/lib:存放组件源码
  • components/css:存放可能需要用到的css样式(自定义)
  • components/lib/xxx/index.js:将组件注册魏全局组件
  • examples:最初项目的src,我们可以一边开发一边调试

注意:更改上述目录之后,配置文件也需要进行相应的改变,因为在webpack中,默认以sec/main.js作为入口文件,现我们已将scr->example,所以入口文件应该进行相应的修改

组件开发

这里以Loading组件为例,

  • components/lib/Loading/src/Loading.vue:组件源码
  • components/lib/Loading/src/index.js:单个注册全局组件
  • components/css/loading.scss:存放Loading组件的样式(这里使用的是scss方式,后面关于打包会提到)
  • components/lib/index.js:所有组件的全局注册

代码实例如下:

components/lib/Loading/src/Loading.vue

<template><div class="beva-loading"><img class="loading-icon" :src="imgSrc" alt=""></div>
</template>
<script>export default {name: 'Loading',props: {imgSrc: {type: String,default: ''},},data() {return {}}
}
</script>

components/lib/Loading/src/index.js

import Loading from './src/Loading.vue'Loading.install = function (Vue) { Vue.component(Loading.name, Loading)
}
export default Loading

components/css/loading.scss

	.beva-loading {background-color: rgba(0, 0, 0, 0.7);border-radius: 0.4rem;color: #ffffff;position: fixed;z-index: 99;width: 7.46rem;height: auto;padding: 0.8rem;text-align: center;top: 20vh;box-sizing: border-box;margin-left: -3.73rem;left: 50%;}.loading-icon {width: 4rem;height: 4rem;animation: rotatingright 1s linear infinite;}/*自定义动画类----顺时针旋转(使用这个动画的时候才设置动画执行时间)*/@keyframes rotatingright {transform-origin: 50% 50%;0% {transform: rotate(0deg);}50% {transform: rotate(180deg);}100% {transform: rotate(360deg);}}/*自定义动画类----逆时针旋转(使用这个动画的时候才设置动画执行时间)*/@-webkit-keyframes rotatingleft {0% {-webkit-transform: rotate(0deg);}50% {-webkit-transform: rotate(-180deg);}100% {-webkit-transform: rotate(-360deg);}}

components/lib/index.js

// 将组件库中定义的所有组件引进来,然后再导出
import Demo from './demo';
import Card from './card';
import Loading from './Loading';const components = {Demo,Card,Loading
}
const install = function (Vue) { // 判断是否安装,安装过就不继续往下执行if (install.installed) returnObject.keys(components).forEach(component => { Vue.component(components[component].name, components[component])})
}
export default {install
}

新建webpack.components.js文件,其中主要是对组件打包的配置

1.对打包输出的文件进行处理

2.如果用到了scss、css,图片,则还需要对这些文件进行额外处理

主要配置如下(其中有相关的注释,有兴趣可以自行查看)

const { VueLoaderPlugin } = require('vue-loader');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const glob = require('glob')
const path = require('path')
const list = {}// 动态导入多个组件的入口文件
// 封装组件的一些配置,因为组件打包是单独打包的,所以需要单独配置
async function makeList (dirPath, list) {// 拿到所有的入口文件的路径const files = await glob.sync(`${dirPath}/**/index.js`)//[ 'components/lib/button/index.js', 'components/lib/icon/index.js']// 取出上一级目录的文件名files.forEach(file => {let name = file.split('/')[2]// 判断name是否有后缀名,有的话去除if (name.includes('.')) {name = name.split('.')[0]}list[name] = `./${file}`})// console.log(list)
}
makeList('components/lib', list)
module.exports = {entry: list,mode:'development',output: {filename: '[name].umd.js',// webpack打包的时候会将name替换成入口的name名字,例如card.umd.jspath: path.resolve(__dirname, 'dist'),library:'mui',libraryTarget: 'umd',// 指定输出格式,umd是一种模块,兼容了CommonJS、AMD、CMD},plugins: [new VueLoaderPlugin(),new CleanWebpackPlugin()],module: {// 配置rules,即什么样的文件,使用什么样的loaderrules: [{test: /\.vue$/,use: [{loader: 'vue-loader',}]},{test: /\.css$/,use: ['style-loader','css-loader']},// 这里只处理了css,而项目中组件中使用了scss文件,对于scss文件的处理这里使用的是gulp,下面会提到{test: /\.(png|jpg|gif|svg)$/i, // 匹配图片文件格式type: 'asset/resource', // 使用内置的asset模块处理资源文件generator: {filename: 'images/[name][ext]', // 输出的文件名格式},},],},
}

ps:对于组件中使用的scss文件的处理,这里用到的是gulp,具体设置如下:

新建gulpfile.js,对css文件单独打包(下方用到的第三方依赖需要自定下载

const gulp = require('gulp');
// 需要把样式代码导入
const sass = require('gulp-sass')(require('sass'));
// 对css代码进行压缩
const minifyCSS = require('gulp-minify-css');
gulp.task('sass', async function () {return gulp.src('components/css/**/*.scss').pipe(sass())// 将scss代码转换成css代码.pipe(minifyCSS())// 压缩css代码.pipe(gulp.dest('dist/css'))// 输出到打包目录
})

接下来就是新增打包命令:

在package.json文件中

最后的打包文件如下:

上传npm

修改package.json文件

在上传npm之前呢,我们有必要对这个组件库信息进行相应的配置,因为npm上发布的包是根据package.json的文件进行匹配的,所以,进行如下信息修改,一般指定如下信息

  • 删除私有属性private
  • description:描述
  • main:入口文件
  • keywords:关键字(方便用户搜索)
  • author:作者信息
  • files:望发布的文件目录(不需要将所有文件都上传到npm中)

距离如下:

添加md文件

打包&&发布

由于这里封装组件的方式是打包发布的方式,所以切记在发布之前进行打包,生成dist文件!

维护版本

手动修改package.json中的version或者执行npm version patch生成迭代一个版本

执行打包命令

npm run build

登陆npm

注意这一需要登陆官方仓库,如果之前连接的是淘宝镜像需要线切换回来。下面是查看仓库源和切换仓库的命令。

npm config get registry  // 查看仓库源
npm config set registry https://registry.npm.taobao.org
npm config set registry http://registry.npmjs.org 

 登陆npm,输入账号、密码、邮箱

npm login

 发布

npm publish

测试组件

安装

npm i vue-library-ui

引入&&使用 

 页面

 扩展

我在这个的基础上封装了另外一个组件vue2-edit-cron,主要是可以快速构建cron表达式,有兴趣也可以看看~:vue2-edit-cron - npm (npmjs.com)

总结

        该文组件封装的方式其实是打包发布的方式,这种方式是将装好的组件最终打包成一个或者多个js文件发布。这种方式使得开发和调试时更接近于一个前端项目。但是一旦引入图片等静态资源需要同个BASE64的方式打包到js,而对于字体一类较大的静态资源则根本无法引用

适用范围:没有或极少的依赖第三方插件、图片的组件的封装或JS方法的封装

后面经过了解知道,其实还有另外一种方式即,非打包方式,具体的对比如下:

打包发布非打包发布
webpack需要配置无需配置
发布发布前需要打包发布前无需打包
引用静态文件较小的图片可以通过BASE64方式打包仅js文件随意使用
引用第三方依赖可以引用,但如果第三方依赖包含较多的静态文件时可能会出现引用不到的情况随意引用
被应用的文件一个打包好的js组件的入口文件
调试方法在组件项目中即可调试需要在引用组件的项目中的node_module中对用模块中调试

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Java中实现线程同步

在Java中实现线程同步是多线程编程中的一个重要概念&#xff0c;目的是控制对共享资源的访问&#xff0c;以防止多个线程同时修改某一资源&#xff0c;从而避免数据的不一致性和发生冲突。以下是几种在Java中实现线程同步的方法&#xff1a; ### 使用synchronized关键字 sync…

使用 MyBatis 的 mapper 接口调用时的要求

1&#xff1a; Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同&#xff1b; 2&#xff1a; Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的parameterType 的类型相同&#xff1b; 3&#xff1a; Mapper 接口方法的输出参数类型和 mapper.xml 中…

SAM5716B 法国追梦DREAM 音频DSP芯片

法国追梦/DERAM SAM5504/5704/5716/5808音频DSP芯片,开发板&#xff0c;方案 可用于电子鼓、电子琴、电吉他、效果器、均衡器、啸叫抑制器等电声产品领域 全系列芯片&#xff1a; SAM2634 SAM2695 SAM5504B SAM5704B SAM5708B SAM5808B SAM5716B SAM5916B... 原厂开发…

根据状态转移图实现时序电路

描述 某同步时序电路的状态转换图如下&#xff0c;→上表示“C/Y”&#xff0c;圆圈内为现态&#xff0c;→指向次态。 请使用D触发器和必要的逻辑门实现此同步时序电路&#xff0c;用Verilog语言描述。 如图所示&#xff1a; 电路的接口如下图所示&#xff0c;C是单bit数据…

密码学 | 承诺:常见的承诺方案

&#x1f951;原文&#xff1a;密码学原语如何应用&#xff1f;解析密码学承诺的妙用 - 知乎 1 简介 密码学承诺 涉及 承诺方、验证方 两个参与方&#xff0c;以及以下两个阶段&#xff1a; 承诺阶段&#xff1a;承诺方选择一个敏感数据 v v v&#xff0c;为它计算出相应…

国家信息安全漏洞库(CNNVD)技术支撑单位等级证书

国家信息安全漏洞库&#xff08;CNNVD&#xff09;技术支撑单位等级证书是CNNVD对参与信息安全漏洞研究、事件解读、漏洞信息共享等工作的单位进行认证和评级的机制。该证书有助于提升单位在信息安全领域的影响力和公信力&#xff0c;同时也是对单位技术实力和贡献的一种认可。…

AUTOSAR ARXML处理 - C#的解析代码(四)

4.3 配置参数关键类 4.3.1 配置数据&#xff1a;模块 MODULE &#xff08;ECUCMODULECONFIGURATIONVALUES&#xff0c;<ECUC-MODULE-CONFIGURATION-VALUES>&#xff09; 与ECUCMODULEDEF&#xff0c;<ECUC-MODULE-DEF> 关联 /// <remarks/>[System.CodeDom…

标题:探索算法世界的奇妙与力量

标题&#xff1a;探索算法世界的奇妙与力量 在当今信息时代&#xff0c;算法已经成为了我们生活中不可或缺的一部分。从搜索引擎、社交媒体&#xff0c;到无人驾驶、机器人&#xff0c;算法都在其中发挥着重要的作用。本文将为您详细介绍算法的概念、类型、应用场景以及算法的…

美国家安全局等发布安全部署人工智能系统指南

该指南旨在为部署和运行由其他实体设计和开发的人工智能系统的组织提供最佳实践。 2024年4月15日&#xff0c;美国国家安全局发布了名为《安全部署人工智能系统&#xff1a;部署安全、弹性人工智能系统的最佳实践》&#xff0c;该指南旨在为部署和运行由其他实体设计和开发的人…

【Jupyter Notebook】快捷键

在命令模式下&#xff0c;单元格边框是灰色&#xff08;缺省&#xff09;的。这些快捷键主要用于操作单元格。 Enter&#xff1a;进入编辑模式Shift Enter&#xff1a;运行当前单元格并选中下一个单元格Ctrl Enter&#xff1a;运行当前单元格Alt Enter&#xff1a;运行当前单…

类声明是public类型的变量如何赋值

在面向对象编程(如Java、C#、PHP等语言)中,类声明为public类型的变量是类的成员变量,也称为属性或字段。这些变量可以在类内部、构造函数中、或者从类外部通过实例化对象来赋值。以下是一些基本的赋值方式: 在类内部赋值: // Java 示例 public class MyClass {public S…

途游游戏,科锐国际(计算机类),得物,蓝禾,奇安信,顺丰,康冠科技,金证科技24春招内推

途游游戏&#xff0c;科锐国际&#xff08;计算机类&#xff09;&#xff0c;得物&#xff0c;蓝禾&#xff0c;奇安信&#xff0c;顺丰&#xff0c;康冠科技&#xff0c;金证科技24春招内推 ①得物 【岗位】技术&#xff0c;设计&#xff0c;供应链&#xff0c;风控&#xff0…

Mac多媒体播放器 Movist Pro v2.11.4中文激活版下载

Movist Pro for Mac是一款专业的媒体播放器&#xff0c;特别为Mac用户设计。它不仅界面简洁美观&#xff0c;而且功能强大&#xff0c;能满足用户各种播放需求。 Movist Pro v2.11.4中文激活版下载 首先&#xff0c;Movist Pro for Mac支持多种媒体文件的播放&#xff0c;包括视…

关于Qt主窗口的菜单部件

前言 在介绍主窗口的两大部件之前&#xff0c;我们要先知道关于主窗口的一些知识。 主窗口 一个主窗口可以没有菜单条、工具条、状态条&#xff0c;但必须设置中心部件。在 Q 生成的 C头文件 ui_mainwindow.h 代码中,我们可以看到以下代码: centralWidget new Qwidget(MainWi…

CSS基础常用属性之颜色(如果想知道CSS的颜色知识点,那么只看这一篇就足够了!)

前言&#xff1a;在我们学习CSS的时候&#xff0c;主要学习选择器和常用的属性&#xff0c;而这篇文章讲解的就是最基础的属性——颜色。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 目录 1.颜色属性 【1】使用颜色关键词表…

深入理解Vue 3中的自定义Hooks

开始 Vue 3引入了Composition API&#xff0c;这使得我们可以更自由、更灵活地组织组件的逻辑代码。其中&#xff0c;自定义Hooks是Composition API的一个重要特性&#xff0c;它允许我们将可复用的逻辑抽象成独立的函数&#xff0c;并在不同的组件中进行共享和复用。本文将深…

fatal error C1001: An internal error has occurred in the compiler

VS2008驱动项目A&#xff0c;集成一个Wzarid生成的驱动LIB项目B&#xff0c;在编译64位驱动时,出现以下错误&#xff1a; 1>------ Build started: Project: xxxx, Configuration: Release x64 ------ 1>Linking... 1>fatal error C1001: An internal error has occu…

Android 应用分配的内存大小是多少

Android应用给定的内存大小可以因设备而异&#xff0c;主要受设备的硬件配置和操作系统的限制。不同的设备&#xff0c;尤其是有着不同RAM大小的设备&#xff0c;可能会为应用分配不同的最大内存数量。此外&#xff0c;同一个设备上&#xff0c;不同版本的Android操作系统也可能…

MySQL常见函数的讲解

函数:将某些功能封装到一起&#xff0c;对外提供到一个接口(函数名)&#xff0c;通过函数调用的方式可以重复的执行函数里的功能&#xff0c;从而提高我们的代码的复用性。 MySql里自带了很多已经封装好了的函数,可以帮我们实现很多功能 MySql里调用函数和java一样用函数名()…

怎么在 Spring 服务响应时控制响应时间?

在Spring应用程序中控制服务响应时间是确保系统性能和用户体验的关键方面之一。在处理请求时&#xff0c;响应时间是指从客户端发送请求到服务端返回响应所花费的时间。 在某些情况下&#xff0c;需要对响应时间进行控制&#xff0c;以确保系统能够及时响应用户请求&#xff0…