之前工作中组件都是封装在项目里,最近总想鼓捣一个组件发布到npm上并供大伙使用,所以参考了一些文章弄了一下,当然使用的是最新的vuecli3工具其中的vue-cli-service build --target lib 文末我会通过源码讲解下lib 定制化的输出umd模式的.min.js 不需要输出多余的文件
我的项目地址
- github.com/HeJinG90/al… 欢迎star,是一个图片上传的组件,图片传到alioss上
- 对象存储oss 官网 help.aliyun.com/document_de… 可以了解一波
一、技术栈
vuecli3
二、效果演示
三、创建项目
通过vuecli3创建一个初始化项目,具体可以查看官网。cli.vuejs.org/zh/guide/cr…
四、调整项目结构
我们需要一个文件夹存放组件,一个文件夹存放示例,按照以下方式对目录进行改造。
- examples // 原 src 目录,改成 examples 用作示例展示
- packages // 新增 packages 用于编写存放组件,如下图为我的项目结构
五、配置项目以支持新的目录结构
src目录更名为examples,导致项目无法运行
-
注:vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。
-
重新配置入口,修改配置中的 pages 选项
-
新版 Vue CLI 支持使用 vue.config.js 中的 pages 选项构建一个多页面的应用。
-
这里使用 pages 修改入口到 examples,设置css不单独提取。
module.exports = {
// 修改 src 目录 为 examples 目录
pages: {
index: {
entry: 'examples/main.js',
template: 'public/index.html',
filename: 'index.html'
}
},
css: { extract: false }
}
六、编写组件
以上我们已配置好对新目录架构的支持,接下来我们尝试编写组件。以下我们以一个已发布到 npm 的小插件作为示例。具体代码可以看我项目源码,我大概说下思路:
- 在 packages 目录下,所有的单个组件都以文件夹的形式存储,所以这里创建一个文件夹 uploadpictures
- 在 uploadpictures 文件夹下创建 src 文件夹存储组件源码
- 在 /uploadpictures 文件夹下创建 index.js 文件对外提供对组件的引用。
- 修改 /packages/uploadpictures/index.js文件,对外提供引用。
- 创建组件的统一入口文件/packages/index.js,导出组件,其实跟elementui差不多 还可以改造成按需引入。
- tip: 当然我的组件里面有引用到elementui框架中的message和loading组件,在此感谢饿了吗团队组件框架解耦的比较好,我便抽取出来拿来用了。创建了loading message utils 三个文件夹。
- 然后就是引用
import Vue from 'vue'
import Loading from '../../loading/index'
Vue.use(Loading)
import Message from '../../message/index'
Vue.prototype.$message = Message;
import '../../loading/src/loading.css';
import '../../message/src/message.css';
七、编写示例代码
在examples文件夹里编写
<template>
<div id="app">
<uploadPictures @change = "getimg" :imgs = imgs :ossconfig = ossconfig :quality = 1 :dir = dir :size = 200 :num = 3 ></uploadPictures>
</div>
</template>
<script>
import Vue from 'vue'
// 导入组件
import uploadPictures from '../packages/index'
// 使用组件
Vue.use(uploadPictures)
export default {
name: 'app',
data(){
return{
imgs:[], // 图片数组
ossconfig:{
accessKeyId: '',
accessKeySecret: '',
bucket: '',
region: 'oss-cn-beijing'
},
dir:'/images/' //目录文件夹
}
},
methods:{
getimg(e){
this.imgs = e;
},
}
}
</script>
八、发布到 npm,方便直接在项目中引用
-
到此为止我们一个完整的组件已经开发完成了,接下来就是发布到 npm 以供后期使用。
-
在package.json 中新增一条编译为库的命令
-
tip:在库模式中,Vue是外置的,这意味着即使在代码中引入了 Vue,打包后的文件也是不包含Vue的。
-
Vue Cli3 构建目标:库
-
以下我们在 scripts 中新增一条命令 npm run lib
--target: 构建目标,默认为app。这里修改为 lib 启用库模式。 --dest : 输出目录,默认 dist。这里我们改成 lib
- 最后一个参数为入口文件,默认为 src/App.vue。这里我们指定编译 packages/ 组件库目录。
"scripts": {
"lib": "vue-cli-service build --target lib --name alioss-uploadpictures --dest lib ./packages/index.js"
}
执行编译库命令
$ yarn lib
- 打包出来的文件
- 正常来说到这已经可以了,但是package.json里面main字段只需要其中到umd.min.js所以我要去源码对- 其生成的多余文件进行改造,重点来了哈。我们来到node_modules 文件夹 找到@vue/cli-service 依赖包。
- 我们先去index.js中把formats改下,
- 接着我们去resolveLibConfig.js中修改下面的代码,当然通读人家源码不可能,有需求就去看下源码,改一下就好。
- 最后的结果当然是只生成两个文件,因为默认是启用了sourcemap,所以会生成一个对应的.map文件
配置 package.json 文件中发布到 npm 的字段 里面有几个重要的我提一下
- name: 包名,该名字是唯一的。可在 npm 官网搜索名字,如果存在则需换个名字。
- version: 版本号,每次发布至 npm 需要修改版本号,不能和历史版本号相同。
- main: 入口文件,该字段需指向我们最终编译后的包文件。
- private:是否私有,需要修改为 false 才能发布到 npm
- license: 开源协议
- 当然可以参考我的package.json文件,我重点说一下peerDependencies这个属性,这个属性的意思是当前的组件要依赖于哪个包 ,比如我这个组件肯定要依赖vue包,写上版本就好了。还有需不需要在dependencies里面写依赖看自己的情况,如果你写的依赖版本高于宿主环境,可能会造成错误,所以我这不需要写,因为alioss依赖不提供按需引用,所以全部打包到生成到文件里了。
- 再说个重点,根据vuecli官网的指示: 构建库或是 Web Component 时的 Polyfills 当使用 Vue CLI 来构建一个库或是 Web Component 时,推荐给 @vue/babel-preset-env 传入 useBuiltIns: false 选项。这能够确保你的库或是组件不包含不必要的 polyfills。通常来说,打包 polyfills 应当是最终使用你的库的应用的责任。所以我们设置 babel.config.js,这样会减少生成文件的体积。
module.exports = {
presets: [
['@vue/cli-plugin-babel/preset', {
"useBuiltIns": false
}]
]
}
添加 .npmignore 文件,设置忽略发布文件
- 我们发布到 npm 中,只有编译后的 lib文件夹、examples文件夹、package.json、README.md才是需要被发布的。所以我们需要设置忽略目录和文件。
# 忽略目录
packages/
public/
# 忽略指定文件
vue.config.js
babel.config.js
登录到 npm
首先需要到 npm 官网上注册一个账号,这个不是这篇文章重点,自己百度下就好。
$ npm login
发布到 npm
执行发布命令,发布组件到 npm
$ npm publish
发布成功
发布成功后稍等几分钟,即可在 npm 官网搜索到。以下是刚提交的 alioss-uploadpictures
使用新发布的组件库
安装
yarn add alioss-uploadpictures
使用
import Vue from 'vue'
import uploadPictures from 'alioss-uploadpictures'
Vue.use(uploadPictures)
例子
具体参数以及使用可以点击下面的github地址九、项目地址
Github 地址:github.com/HeJinG90/al…
npm 地址:www.npmjs.com/package/ali…