持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天, 点击查看活动详情
先看完再操作,先看完再操作!!!
前提:之前公司做的某个项目中需要用到三栏穿梭框(也就是中间是源数据,数据能够在三个穿梭框中穿梭),因为搜查了一下网上都没有适合的组件使用,于是基于elementui中的transfer穿梭框代码弄了一个三栏穿梭框的组件,如下图所示
考虑到之后可能还会需要用到,如果之后其他项目需要,再去找该项目中复制粘贴就显得有点麻烦和不太方便,所以打算将这个组件发布到npm上,于是参考了一下网上的方法发布到npm上。
1. vue init webpack 项目名称(如果 vue create是没有webpack配置的,因为我参考的博客是有webpack的,所以我选择这样子新建项目)
2.在与src同级下创建packages文件夹,创建具体的组件并写上注脚信息,详细参考该博客【如果不是基于某个ui框架,全部都是自己写的组件内容,我建议看这个博客】,因为下面都是以三栏穿梭框组件为例,下面transferThree中的结构直接基于elementui框架中的node\_modules\element-ui\packages\transfer来二次开发(所以所谓的index.js脚本我这里是不用写的),如下图
vue-transfer—three
|— build // 构建配置
|— webpack.base.conf.js // 基础构建配置
|— webpack.prod.conf.js // 打包(正式环境)的构建配置
...
|— packages // 组件内容
|— transferThree // 具体的组件(这个组件原始是在node_modules\element-ui\packages\transfer复制过去,再修改里面代码成三栏的)
|— src
|-main.vue
|-transfer-panel.vue
|— index.js // 该组件的组测脚本
|— src
|— ...
|— index.js // 自定义组件的打包脚本(组件库的入口)
|— main.js // 项目的本地运行和构建项目脚本
|— package.json
|— README.md
这里的packages\transferThree\index.js(就是node\_modules\element-ui\packages\transfer 下的)
import Transfer from './src/main';
/* istanbul ignore next */
Transfer.install = function(Vue) {
Vue.component(Transfer.name, Transfer);
};
export default Transfer;
3.创建组件库入口脚本index.js(与src下的main.js平级)
// index.js (在src下方,与main.js平级)
import transferThree from '../packages/transferThree/index';
const components = [transferThree]
const install = function(Vue,opts={}) {
components.forEach(component => {
Vue.component(component.name, component)
})
}
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
install,
transferThree
}
如果依赖第三方UI库, 要引入,这里我是基于elementUI的,所以在使用该组件的时候需要引入
// 如果依赖第三方UI库, 要引入,这里我是基于elementUI的,所以需要引入
import Vue from 'vue'
import ElementUI from 'element-ui'
Vue.use(ElementUI)
import 'element-ui/lib/theme-chalk/index.css'
4.修改webpack.base.conf.js
export default {
entry: process.env.NODE_ENV === 'production' ? './src/index.js' : './src/main.js',
output: {
path: config.build.assetsRoot,
filename: 'index.min.js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath,
library: 'Application', // 指定的就是你使用require时的模块名
libraryTarget: 'umd', // 指定输出格式
umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
}
}
5.修改 webpack.prod.conf.js
// 这里主要修改 plugins中间的配置 主要就保留以下两个插件即可
plugins: {
// 关于js的压缩插件
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: false,
parallel: true
}),
// 关于css的压缩
new ExtractTextPlugin({
filename: 'index.min.css'
}),
}
6.修改package.json文件
{
"name": "@chorkiu/vue-transfer-three",
"version": "0.0.1",
"description": "transferThree component",
"author": "XX <XX@qq.com>",
"private": false, // 公开的
"main": "dist/index.min.js", // 打包后文件入口
"files": ["dist","packages"], // npm发布的文件包含
"keywords": ["vue","components","element","transfer"],
// "homepage": "",
// "bugs": {
// "url":""
// },
// "repository": {
// "type": "git",
// "url":""
// },
}
7.编辑打包,测试插件
// 编译打包
npm run build
// 测试插件
npm pack
// npm pack之后项目根目录会生成一个tgz文件,这里是chorkiu-vue-transfer-three-0.0.1.tgz
//npm pack之后生成的插件
npm install 绝对路径\chorkiu-vue-transfer-three-0.0.1.tgz
//如果用vscode,可以选中tgz文件右击选择复制路径即可)
8.项目引入插件并测试
安装插件之后,查看node_module有该文件
在App.vue测试,因为这里我是基于elementui,并且webpack配置的时候运行入口文件是main.js,所以这里我main.js还需引入elementui的(我查了很多相关的,不知道是哪一步出错,反正如果像他们那样子直接这样写,例如: import transferThree from '@chorkiu/vue-transfer-three' 我会报错,感觉这里我这里的index.min.js没有生效,但之后我看了node_modules,发现我写多几层也能用,所以就先这样解决)
<template>
<div id="app">
<transferThree></transferThree>
</div>
</template>
<script>
import transferThree from '@chorkiu/vue-transfer-three/packages/transferThree'
export default {
name: 'App',
components: {
transferThree
}
}
</script>
9.最后打开浏览器测试引入插件是否正常显示我们的插件
噔噔蹬蹬!!!完美呈现了!之后就是上传到到npm的问题了
10.发布自定义插件到npm
(1)登录npm(如果没有npm账户就先注册一个,login之后需要填username,password等,按着步骤操作即可 )
npm login
(2)发布到npm上(由于起名的时候添加了@name/包名,会默认为私有包,私有包是需付费的,所以如果起名的时候像我那样,那就要加后缀改成公开的)
npm publish // 正常的只要这样子即可
npm publish --access public // packages.json的name命名格式是@your-name/包名,需要加后缀变公开的
这样就发布成功了!!!
这里面还有一个小小插曲是npm login有问题,报E426上面所说的因为name导致的私有包问题等问题,都卡着卡着解决了!
!!!注意注意:因为我name是@name/包名 ,虽然发布的时候添加--access public发布成功,但是之后我从npm 下载是失败的,反正最后的最后,我的package.json里面的name不再是@name/包名 这种形式,而是直接包名的!!!还有就是package.json中的name和你该项目文件名不能重复,不然你安装npm pack出来的那个.tgz文件是会提示报错的!!!
参考过的原博客:
下面这两个链接其实解决的是同一个问题,方法几乎一样,只是这两个中都有写错的bug,综合才是正确的解决方法,后续我会归纳一下