先说一下这篇文章的诞生原因。我们有一个这样的项目,类似或者说就是一个仪表板-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. 阿里巴巴 Kubernetes 能力再获 CNCF 认可 | 云原生生态周报 Vol. 32

    作者 | 丁海洋  陈有坤 李鹏  孙健波 业界要闻 阿里巴巴 Kubernetes 技术能力再获 CNCF 认可 CNCF 官网发布博文<Demystifying Kubernetes as ...

  2. redis的介绍与操作及Django中使用redis缓存

    redis VS mysql的区别 """ redis: 内存数据库(读写快).非关系型(操作数据方便) mysql: 硬盘数据库(数据持久化).关系型(操作数据间关系) ...

  3. 微信支付 第一篇 JSAPI 支付配置与获取 OpenID

    开通微信支付支付产品 首先要在微信支付申请成为 微信支付商户. 选择开通具体的支付产品 成为微信支付商户后在管理后台选择微信支付中的具体支付产品并申请开通如 JSAPI . 将支付商户与公众号关联 这 ...

  4. C# WinForm界面美化--使用IrisSkin实现换肤功能

    WinForm界面使用IrisSkin,可以说做到了一键美化,当然美化的效果仁者见仁智者见智,可以挑选自己喜欢的. 1.IrisSkin下载地址:https://www.cr173.com/soft/ ...

  5. sleuth和zipkin微服务里的链路跟踪

    分布式链路跟踪介绍 对于一个微服务系统,大多数来自外部的请求都会经过数个服务的互相调用,得到返回的结果,一旦结果回复较慢或者返回了不可用,我们就需要确定是哪个微服务出了问题.于是就有了分布式系统调用跟 ...

  6. FCC---CSS Flexbox: Add Flex Superpowers to the Tweet Embed

    To the right is the tweet embed that will be used as the practical example. Some of the elements wou ...

  7. Android Studio 使用Memory Monitor进行内存泄露分析

    在使用Android Studio进行内存泄露分析之前,我们先回顾一下Java相关的内存管理机制,然后再讲述一下内存分析工具如何使用. 一.Java内存管理机制 1. Java内存分配策略 Java ...

  8. 《收获,不止SQL优化》这本书,有很多即用的脚本工具,或者根据自己的需求,改造重用,可以积累到自己的工具库中。

    以下两个脚本,官方来源: https://github.com/liangjingbin99/shouhuo/tree/master/%E7%AC%AC05%E7%AB%A0 1. 找出未使用绑定变量 ...

  9. JAVA开发几个常用快捷键

  10. 设置fiddler抓取安卓手机的包

    1.在手机端设置代理,IP地址为fiddler所在电脑IP,端口默认8888 2.在fiddler上打开工具-设置-连接,勾选允许远程计算机连接,点击确定 3.安装证:手机浏览器输入 http://( ...