先说一下这篇文章的诞生原因。我们有一个这样的项目,类似或者说就是一个仪表板-Dashboard,其中的各个部分可能不是一个部门写的……我们需要提供拖拽布局(大小和位置)和展示的能力。要实现这样一个功能,想了好几种方式实现(后面的笔记详说),最后选择了这篇笔记的实现方式:写整个项目的,算是使用方;写每个组件的,算是vue类库(UI、组件库)的提供方。之后就是我们如何使用这些类库的问题了,就像我们使用element-ui一样,这样说就明白了吧!这里不说父子之间如何通信以及如何使用类库,只说如何打包类库。

  之前总是使用别人的类库了,没有自己写过,今天就着这个机会研究了有了一下,demo算是跑通了,深入的就需要之后慢慢学习了。

  开始还是看了一下element-ui是如何将所有的组件打包到一个JS文件,并且可以CDN方式使用的,发现和我们写一个单独的.vue单文件组件没有什么区别,主要是webpack的output和入口文件的写法有些不同,其他的都大同小异,先看一下output

var path = require('path');
var VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
mode: 'development', // production|development // https://segmentfault.com/a/1190000013712229
entry: "./index.js",
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'ddztestlib01.js',
library: 'ddztestlib01',
libraryTarget: 'umd',
libraryExport: 'default',
umdNamedDefine: true,
// globalObject: `(typeof self !== 'undefined' ? self : this)`, // https://stackoverflow.com/questions/49111086/webpack-4-universal-library-target
globalObject: 'typeof self !== \'undefined\' ? self : this' // element-ui 写法
},
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader'
}, {
test: /\.css$/,
loader: 'css-loader'
}, {
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
}]
},
devtool: "source-map",
resolve: {
alias: {
'vue': 'vue/dist/vue.js'
}
},
plugins: [
new VueLoaderPlugin()
]
}

webpack.config.js

  这里主要说一下,libraryTarget、libraryExport、umdNamedDefine和globalObject

  1、libraryTarget:打包类库的发布格式,这里使用UMD,其他选项不解释(其实是……)

  2、libraryExport:这个选项同样不知道干什么的,但是我遇到了一个问题就是开始没有添加这个选项(虽然看了element-ui的打包,但是我给过滤了),导致使用的时候发现有双层的“default”,因为不是很了解,所以查了一些资料先看看,却发现和这篇文章说的一样:webpack组织模块打包Library的原理及实现,后来发现该文中使用的选项过期了,之后还是又看了一遍element-ui 才搞定,这一大圈

  3、umdNamedDefine:这个还是同上,但是添加和不添加这个选项比较一下生成文件你就知道了

  4、globalObject:这个是真不知道了,但是在stackoverflow中无意发现说这是个Bug,地址:https://stackoverflow.com/questions/49111086/webpack-4-universal-library-target

  现在看来webpack配置文件处理output某些属性和我们正常开发没有什么区别,下面看一下他的入口文件:

//  1、这里导入需要导出的组件,统一处理
import DDZComponent01 from './src/components/DDZComponent01.vue';
import DDZComponent02 from './src/components/DDZComponent02.vue';
// 1.1、书写Vue插件(保证只引入某一个组件时可用),https://cn.vuejs.org/v2/guide/plugins.html
DDZComponent01.install = function (Vue) {
Vue.component(DDZComponent01.name, DDZComponent01);
};
DDZComponent02.install = function (Vue) {
Vue.component(DDZComponent02.name, DDZComponent02);
}; // 2、遍历注册所有的组件(依赖),全局时使用
const components = [
DDZComponent01,
DDZComponent02
];
const install = function (Vue, opts = {}) {
components.forEach(component => {
Vue.component(component.name, component);
});
// 这里除了注册组件,还可以做一些其他的东西
// 你可以在Vue的原型上扩展一些方法
// eg:element-ui
// Vue.prototype.$message = Message;
// 使用:this.$message({message:"xxxxx",type:"success"});
}; // 可以根据实际情况,是否需要这段代码(CDN引入,便可使用所有组件)
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
// 3、导出类库的版本、组件、Vue插件需要暴露的install方法
export default {
version: '0.0.1',
install,
DDZComponent01,
DDZComponent02
}; // 4、使用方式
// 4.1、使用部分组件
// 4.1.1、
// import { DDZComponent01 } from '……/ddztestlib01.js';
// 局部注册:components: { ddzcomponent01: DDZComponent01 },
// 全局注册:Vue.use(DDZComponent01); //这种写法需要对应的组件暴露install方法
// 4.1.2、
// import * as ddztestlib01 from '……/ddztestlib01.js'; // 这里的书写方式应该和导出的写法有关系
// 局部注册:components: { ddzcomponent01: ddztestlib01.DDZComponent01 },
// 全局注册:Vue.use(ddztestlib01.DDZComponent01); //这种写法需要对应的组件暴露install方法
// 4.2、使用类库中的所有组件
// 4.2.1、
// import * as ddztestlib01 from '……/ddztestlib01.js'; // 这里的书写方式应该和导出的写法有关系
// Vue.use(ddztestlib01); //这里的使用就是调用对象的install方法
// 4.2.2、cdn方式使用
// <script src="……/ddztestlib01.js"></script> //如果window.Vue存在,则自动注册全部组件
// 4.3、使用systemjs异步加载(测试版本:SystemJS 3.1.6)
// 加载之后,返回的是该类库的默认导出对象:{default:{version:,install:,……}}。这种加载方式和CDN类似,如果window.Vue存在,则自动注册全部组件。所以如果window.Vue存在,返回的对象意义不大;除非window.Vue不存在。注意:组件注册成功之后在显示
// 代码示例:
// System.import("……/ddztestlib01.js").then((result) => {
// // 成功加载之后,显示组件
// // 如果window.Vue存在,并且存在类似上面的install方法,则这里的返回结果没有什么意思
// // 至于如何使用,则可以根据具体情况而定,选择自己合适的
// });
// 4.4、使用requirejs异步加载(测试版本:requirejs 2.3.6)
// 和systemjs类似,只是使用方式不同
// 代码示例:
// requirejs.config({
// paths: {
// "ddztestlib01": tempUrl
// }
// });
// requirejs(["ddztestlib01"], (result) => {
// // 成功加载之后,显示组件
// });
// 4.5、……使用模块加载器加载JS和CDN方式差不多,只是不同的加载器返回的结果不同(有支持UMD,有的不支持)

index.js

  入口文件就不解释了,在里面我觉得解释的够清楚了,还有类库中包含的组件这里就不说了,也没有什么好说的就是“Hello World”。

  最后在附上使用类库的代码:

<!DOCTYPE html>
<html lang="zh-cmn-Hans"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>测试我的Vue组件库:ddztestlib01</title>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
} html,
body {
height: 100%;
width: 100%;
margin: 0;
} [v-cloak] {
display: none;
}
</style>
</head> <body>
<div id="myApp" v-cloak>
<h3>{{msg}}</h3>
<div>下面是组件1的内容</div>
<ddzcomponent01 :prop1="ddzcomponent01prop1"></ddzcomponent01>
<div>下面是组件2的内容</div>
<ddzcomponent02 :prop1="ddzcomponent02prop1"></ddzcomponent02>
</div>
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<script src="https://xiaodu114.github.io/vue/vue2.x/PackFirstVueLibrary/dist/ddztestlib01.js"></script>
<script>
var myApp = new Vue({
el: "#myApp",
data() {
return {
msg: "测试我的Vue组件库:ddztestlib01",
ddzcomponent01prop1: "我在这里为组件1的属性1赋值:" + new Date(),
ddzcomponent02prop1: "我在这里为组件2的属性1赋值:" + Math.random(),
}
}
});
</script>
</body> </html>

  预览地址

  源码地址

  这篇文章就到这里吧!有写的不对的地方,敬请指正,非常感谢!

利用webpack打包自己的第一个Vue组件库的更多相关文章

  1. webpack 打包和手动创建一个vue的项目

    首先我们为啥要用webpack,为啥不用其他的打包的工具. 先听我捋捋, Webpack有人也称之为 模块打包机 ,由此也可以看出Webpack更侧重于模块打包,当然我们可以把开发中的所有资源(图片. ...

  2. 【万字长文】从零配置一个vue组件库

    简介 本文会从零开始配置一个monorepo类型的组件库,包括规范化配置.打包配置.组件库文档配置及开发一些提升效率的脚本等,monorepo 不熟悉的话这里一句话介绍一下,就是在一个git仓库里包含 ...

  3. 如何从0开发一个Vue组件库并发布到npm

    1.新建文件夹在终端打开执行 npm init -y 生成package.json如下,注意如果要发布到npm,name不能有下划线,大写字母等 { "name": "v ...

  4. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器开放平台利用 webpack 打包压缩后端代码

    需求背景 javaScript的用途是解决页面交互和数据交互,最终目的是丰富客户端效果以及数据的有效传递. 并且具有良好的用户体验. javaScript可以快速实现页面交互,即js操作html的do ...

  5. 写一个vue组件

    写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...

  6. 如何写好一个vue组件,老夫的一年经验全在这了【转】 v-bind="$attrs" 和 v-on="$listeners"

    如何写好一个vue组件,老夫的一年经验全在这了 一个适用性良好的组件,一种是可配置项很多,另一种就是容易覆写,从而扩展功能 Vue 组件的 API 来自三部分——prop.事件和插槽: prop 允许 ...

  7. Laravel 项目中编写第一个 Vue 组件

    和 CSS 框架一样,Laravel 不强制你使用什么 JavaScript 客户端框架,但是开箱对 Vue.js 提供了良好的支持,如果你更熟悉 React 的话,也可以将默认的脚手架代码替换成 R ...

  8. 自己编写并发布一个Vue组件

    自己编写并发布一个Vue组件 1. 几种开源协议的介绍 https://blog.csdn.net/techbirds_bao/article/details/8785413 2.开始编写组件 新建p ...

  9. 一个 VUE 组件:实现子元素 scroll 父元素容器不跟随滚动(兼容PC、移动端)

    介绍 我们经常遇到一种情况.当滑动滚动条区域时,子元素滚动条到底部或顶部时就会触发父级滚动条,父级滚动条同理会继续向上触发,直至body容器.这是浏览器默认的滚动行为. 但是很多情况,我们想要子元素滚 ...

随机推荐

  1. 使用SC命令操作(安装、开启、配置、关闭、删除)Windows下的服务

    目录 一.直接使用cmd命令行操作windows服务 二.使用bat批处理-操作windows服务 一.直接使用cmd命令行操作windows服务 1.安装服务 sc create 服务名 binPa ...

  2. Nginx模块及配置虚拟主机

    1.Nginx的2组主要的模块 (1)core modules (必需,核心模块) 包括:Main.Events (2)Standard HTTP modules(虽然不是必需,但是缺省都会安装,不建 ...

  3. 分布式CAP与BASE理论

    参考: CAP和BASE理论 https://juejin.im/post/5d720e86f265da03cc08de74 https://github.com/changmingxie/tcc-t ...

  4. bootstrap-table 常用总结-1

    两种表格工具,今天都用到了,一种是我前几篇写到过的jqgrid,(传送门)另一个就是bootstrap-table了.用过之后会发现,两种表格的方式大同小异,但是为什么这次要换成bootstrap-t ...

  5. CSS入门(css简介与样式汇总、CSS的使用方式和特征、CSS基础选择器和复杂选择器、边框阴影)

    一.CSS的作用 1.以统一的方式实现样式的定义 2.提高页面样式的可重用性和可维护性 3.实现了内容(HTML)和表示(CSS)的分离 HTML和CSS之间有什么关系? HTML:构建网页的结构 C ...

  6. Android五大布局详解——TableLayout(表格布局)

    TableLayout 前面所学的LinearLayout和RelativeLayout两大布局已经完全适用于各种开发条件下,其他的布局仅供参考学习,毕竟知识就是力量,以后的开发过程中万一遇到也能游刃 ...

  7. Linux(Centos7)下redis5安装、部署、开机自启

    1.什么是redis redis是用C语言开发的一个开源的高性能键值对(key-value)数据库.它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止redis支持的键值数据类型如下字符串 ...

  8. 阿里云ECS服务器部署HADOOP集群(七):Sqoop 安装

    本篇将在 阿里云ECS服务器部署HADOOP集群(一):Hadoop完全分布式集群环境搭建 阿里云ECS服务器部署HADOOP集群(二):HBase完全分布式集群搭建(使用外置ZooKeeper) 阿 ...

  9. javabean的内省(Introspector)

    内省是 Java 语言对 Bean 类属性.事件的一种缺省处理方法.例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值. 通过 getName/ ...

  10. 【西北师大-2108Java】第十四次作业成绩汇总

    [西北师大-2108Java]第十四次作业成绩汇总 作业题目 面向对象程序设计(JAVA) 第16周学习指导及要求 实验目的与要求 (1)掌握Java应用程序的打包操作: (2)掌握线程概念: (3) ...